F-星球大战

题目描述

FF上次在大家的帮助下算出了呼唤到了足够多的人数再一次阻拦了丧心病狂的NE。然后机智的FF为了继续摸鱼决定搬离地球到达BD星来防止NE再次gank。

可是FF错误估计了NE丧心病狂的程度。NE居然拿出了终极武器“朗基努斯之枪”。用“朗基努斯之枪”可以发出激光攻击BD星。NE决定直接摧毁BD星让FF无处可逃。这个时候BD哥站了出来。 

BD哥:“正好试试我新研发的激光抵御装置1.0版本-反射护罩!” FF:“难道是传说中的禁卡,可以破坏敌人所有的攻击表示的怪兽吗!”aBD哥:“FF你在胡说什么。”(说着FF遭到了BD哥的敲打,生命-1。 BD哥详细的给FF解释了一下这个装置的效果: ________________________________________这个装置是一个球体,任何穿过这个球体的激光都会遭到削弱。 为了简化题目,我们将其看做二维平面: 攻击点A即NE所在位置,我们保证反射护罩的圆心的y坐标与攻击点A的y坐标相同。 令y轴为FF所在的BD星的地面。 

每次攻击发射一条激光,有一个初始能量值C i。 
若激光穿过反射护罩,那么它将与反射护罩产生2个交点B,C(更接近A的交点为B,远者为C,保证B、C不重合)。 
记AB长度为a,BC的长度为b,那么这条激光的能量值就会减少a 2+ab。 
削减后能量值如果小于0则光线消失。(即不会有能量值为负的光线到达BD星); 
FF想知道,最后BD星会遭受的总共多少能量值的激光攻击。 

输入描述:

第一行包含一个正整数T(1<=T<=300)。
接下来有T组数据。
每组数据的第一行包含5个整数,xa,ya,xr,r,n(1<=xa,ya,xr,r<=15000;1<=n<=1000),分别代表A的x坐标,A的y的坐标,反射装置的圆心的x坐标,反射装置的半径,与攻击次数。
我们保证攻击点A在圆外并且xa>xr;
接下来n行。每行包含2个整数 y0,Ci(0<=y0<=15000,0<=Ci<10^9),代表A发出的攻击所想要攻击到的目标点(0,y0)和这条激光的能量值Ci。

输出描述:

对于每组数据,输出一行,

包含一个整数,表达受到的所有攻击的能量值的和。

输入

1
3 1 1 1 5
0 2
2 2
1 4
4 10
5 10

输出

21

这题我自己做的,总之就是纯几何,用割线定理a*(a+b)刚好就等于(xa-xr-r)(xa-xr+r)=(xa-xr)^2-r^2
这相当于减少的量,然后如果能量值c减去减少量大于零的话,sum就加上减去后的能量

(然后你就会发现,减少的能量跟纵坐标是完全没关系的……

我就觉得很奇怪啊,那给你纵坐标干嘛呢?
然后我就发现了,原来还有不相交的情况是要用到纵坐标的……)

分开讨论跟圆不相交的情况(包括相切
就用相似三角形把△y算出来,如果y0坐标 >= ya+△y 或者 <= ya-△y,那么没有削弱,能量全部到达
反正我基本是纯手算的。。

#include<stdio.h>
#include <math.h>
#define ll long long

int main()
{
    int n,i,j,t;
    scanf("%d",&t);
    while(t--)
    {
        double xa,ya,xr,r;
        scanf("%lf %lf %lf %lf %d",&xa,&ya,&xr,&r,&n);
        ll sum=0;
        double y,delta,y0;
        int c;
        delta=sqrt((xa-xr)*(xa-xr)-r*r);
        y0=r*xa/delta;                 //相切时纵坐标与ya的差值
        double reduce=(xa-xr)*(xa-xr)-r*r;     //与圆相交时减少的能量
        while(n--) 
        {
            scanf("%lf %d",&y,&c);
            if(y>=ya+y0 || y<=ya-y0)             //不相交的情况
            {
                sum+=c;
            }
            else {
                if(c>reduce)  sum+=c-(ll)reduce;   //相交并且削弱后的能量大于0
            }
        }
        printf("%lld\n",sum);
    }
}

反正主要就是注意一下各种数据类型。。因为用到sqrt函数的时候是要用double的 但是最后sum还是要转换成整数

不过其实我用得也挺乱的……总之  过了就好……

猜你喜欢

转载自www.cnblogs.com/Lyrixblogs/p/10259775.html