HDU5572(计算几何+精度)

来源:互联网 发布:招标文件制作软件 编辑:程序博客网 时间:2024/05/21 22:29

原题:HDU5572

关于精度:关于精度


点关于直线对称公式:

点(x , y )关于直线Ax + by + C = 0 的对称点( X , Y ):


设参数方程


联立圆方程得到关于t的一元二次方程


可见c>0恒成立

分两种情况讨论:

1.小球不反弹

2(1).小球在反弹前已经经过B点

(2).小球反弹后经过b点


对于1,直接检验B是否在射线上(t > 0)

对于2:

要使方程有两个正根,则-b/2a>0,即b<0

其中有效根为较小的t

进而求出反弹点P及切线方程Ax+By+C=0

求出B关于切线对称点C,

检验C是否在射线A上



#include<cstdio>#include<cstdlib>#include<iomanip>#include<iostream>#include<cstring>#include<vector>#include<map>#include<queue>#include<stack>#include<cmath>#include<algorithm>using namespace std;typedef long long ll;typedef long double ld;const ld eps=1e-8;int sgn(ld x){    if(fabs(x)<=eps)    return 0;    else    return x>0?1:-1;}int main(){    int T,cas=1;    scanf("%d",&T);    ld ax,ay,bx,by,ox,oy,vx,vy,r;    ld a,b,c;    ld px,py,t,cx,cy,A,B,C,tp;    while(T--)    {        cin>>ox>>oy>>r;        cin>>ax>>ay>>vx>>vy;        cin>>bx>>by;        printf("Case #%d: ",cas++);        a=vx*vx+vy*vy;        b=2*(ax*vx-ox*vx+ay*vy-oy*vy);        c=ax*ax-2*ox*ax+ox*ox+ay*ay-2*oy*ay+oy*oy-r*r;        if(sgn(b*b-4*a*c)>0&&sgn(b)<0)        {            tp=(-b-sqrt(b*b-4*a*c))/(2.0*a);            px=ax+vx*tp;            py=ay+vy*tp;            if(sgn(vx)!=0)            {                t=(bx-ax)/vx;                if(sgn(by-ay-vy*t)==0&&sgn(t-tp)<=0)                {                    printf("Yes\n");                    continue;                }            }            else if(sgn(vy)!=0)            {                t=(by-ay)/vy;                if(sgn(bx-ax-vx*t)==0&&sgn(t-tp)<=0)                {                    printf("Yes\n");                    continue;                }            }            A=ox-px;            B=oy-py;            C=py*(py-oy)+px*(px-ox);            cx=bx-2.0*A*(A*bx+B*by+C)/(A*A+B*B);            cy=by-2.0*B*(A*bx+B*by+C)/(A*A+B*B);            if(sgn(vx)!=0)            {                t=(cx-ax)/vx;                if(sgn(cy-ay-vy*t)==0&&sgn(t)>0)                printf("Yes\n");                else                printf("No\n");            }            else if(sgn(vy)!=0)            {                t=(cy-ay)/vy;                if(sgn(cx-ax-vx*t)==0&&sgn(t)>0)                printf("Yes\n");                else                printf("No\n");            }        }        else        {            if(sgn(vx)!=0)            {                t=(bx-ax)/vx;                if(sgn(by-ay-vy*t)==0&&sgn(t)>0)                printf("Yes\n");                else                printf("No\n");            }            else if(sgn(vy)!=0)            {                t=(by-ay)/vy;                if(sgn(bx-ax-vx*t)==0&&sgn(t)>0)                printf("Yes\n");                else                printf("No\n");            }        }    }    return 0;}


0 0