An Easy Physics Problem HDU

来源:互联网 发布:程序员的逻辑思维 编辑:程序博客网 时间:2024/06/03 15:17
//#include<bits/stdc++.h>//#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h>#include<algorithm>#include<queue>#include<string.h>#include<iostream>#include<math.h>#include<set>#include<map>#include<vector>#include<iomanip>using namespace std;const double pi=acos(-1.0);#define ll long long#define pb push_backconst double eps=1e-6;int sgn(double x){if(fabs(x)<eps)return 0;if(x<0)return -1;else return 1;}struct Point{double x,y;Point(){}Point(double _x,double _y){x=_x;y=_y;}double distance(Point p){return hypot(x-p.x,y-p.y);}Point operator +(const Point &b)const{return Point(x+b.x,y+b.y);}Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}double operator *(const Point &b)const{return x*b.x+y*b.y;}Point operator *(const double &k)const{return Point(x*k,y*k);}Point operator /(const double &k)const{return Point(x/k,y/k);}double operator^(const Point &b)const{return x*b.y-y*b.x;}double len(){return hypot(x,y);}double len2(){return x*x+y*y;}Point trunc(double r){double l=len();if(!sgn(l))return *this;r/=l;return Point(x*r,y*r);}};struct Line{Point s,e;Line(){}Line (Point _s,Point _e){s=_s;e=_e;}Line(Point p,double angle){//与x轴夹角s=p;if(sgn(angle-pi/2)==0)e=(s+Point(0,1));else e=(s+Point(1,tan(angle)));}double length(){return s.distance(e);}double dispointtoline(Point p){return fabs((p-s)^(e-s))/length();}double dispointtoseg(Point p){if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0)return min(p.distance(s),p.distance(e));return dispointtoline(p);}Point lineprog(Point p){return s+( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) );}};struct circle{Point p;double r;circle(Point _p,double _r){p=_p;r=_r;}int relationline(Line v){double dst=v.dispointtoline(p);if(sgn(dst-r)<0)return 2;else if(sgn(dst-r)==0)return 1;return 0;}int relationseg(Line v){double dst=v.dispointtoseg(p);if(sgn(dst-r)<0)return 2;else if(sgn(dst-r)==0)return 1;return 0;}int pointcrossline(Line v,Point &p1,Point &p2){if(!(*this).relationline(v))return 0;Point a=v.lineprog(p);double d=v.dispointtoline(p);d=sqrt(r*r-d*d);if(sgn(d)==0){p1=a;p2=a;return 1;}p1=a+(v.e-v.s).trunc(d);p2=a-(v.e-v.s).trunc(d);return 2;}};int check(Point A,Point B,Point C){if(B.x==C.x){if((B.y-C.y)*(A.y-C.y)<0)return 1;return 0;}else if(B.y==C.y){if( (B.x-C.x)*(A.x-C.x)<0)return 1;return 0;}if( (B.x-C.x)*(A.x-C.x)<0 )return 1;return 0;}int main(){int T;scanf("%d",&T);int kase=0;while(T--){double x,y,r;scanf("%lf%lf%lf",&x,&y,&r);Point yuanxin=Point(x,y);circle yuan=circle(yuanxin,r);//圆柱 yuanPoint A;scanf("%lf%lf",&x,&y);A=Point(x,y);//源点 Adouble vx,vy;scanf("%lf%lf",&vx,&vy);Line l1;Point to;to=Point(vx+x,vy+y);l1=Line(A,to);//初始直线 l1double bx,by;scanf("%lf%lf",&bx,&by);Point B=Point(bx,by);//终端 BPoint p1,p2;int xiangjiao=0;xiangjiao=yuan.pointcrossline(l1,p1,p2);printf("Case #%d: ",++kase);if(!xiangjiao){if(fabs(l1.dispointtoline(B))<eps){if(int(B.x-A.x)*int(vy)==int(B.y-A.y)*int(vx)){printf("Yes\n");}else{printf("No\n");}continue;}else printf("No\n");}else{//路径直线香蕉//p1,p2是两个直线与圆的交点//要靠近A的交点Point bounce;double dis1=(A.x-p1.x)*(A.x-p1.x)+(A.y-p1.y)*(A.y-p1.y);double dis2=(A.x-p2.x)*(A.x-p2.x)+(A.y-p2.y)*(A.y-p2.y);if(dis1<dis2)bounce=p1;else bounce=p2;Point C=bounce;int way=1;//速度指向圆if(vx==0){if( (C.y-A.y)*vy<0 )way=0;}else if(vy==0){if( (C.x-A.x)*vx<0)way=0;}else{if( (C.x-A.x)*vx<0 || (C.y-A.y)*vy<0)way=0;}//cout<<way<<endl;if(way==1){//会反弹Line l2=Line(B,bounce);if(fabs(l1.dispointtoline(B))<eps){if(check(A,B,C)){printf("No\n");continue;}else{printf("Yes\n");continue;}}else{if(yuan.relationseg(l2)>=2){printf("No\n");continue;}double d1=l1.dispointtoline(yuanxin);double d2=l2.dispointtoline(yuanxin);if(fabs(d1-d2)<eps){//两个直线镜面printf("Yes\n");}else printf("No\n");}}else{if(fabs(l1.dispointtoline(B))<eps){if(int(B.x-A.x)*int(vy)==int(B.y-A.y)*int(vx)){printf("Yes\n");}else{printf("No\n");}continue;}else printf("No\n");}}}}

QAQ !

第一发计算几何题,WA5小时才过去

自己的几何能力还是过得去的,很快想出了最复杂情况的做法

(敲的时候把脑内秒过的简单情况给忘了QAQ

不过因为第一次用模板,接口不熟,把自己坑爆了

刚几何!

原创粉丝点击