ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem
题意:
光滑平面,一个刚性小球,一个固定的刚性圆柱体 ,给定圆柱体圆心坐标,半径 ,小球起点坐标,起始运动方向(向量) ,终点坐标 ,问能否到达终点,小球运动中如果碰到圆柱体会反射。
学到了向量模板,写法简洁。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<iostream> 5 #define clc(a,b) sizeof(a,b,sizeof(a)) 6 #define LL long long 7 #include<cmath> 8 using namespace std; 9 struct node { 10 double dis(node);//两点距离 11 12 //向量操作 13 node add(node);//加 14 double mul(node);//乘 15 node mul(double);//倍 16 double abs();//模长 17 node unt();//单位化 18 node neg();//取反 19 double agl(node);//夹角,度数 20 bool eql(node);//向量相等 21 int pal(node);//向量平行 22 23 double x,y; 24 }; 25 double node::dis(node a) { 26 return sqrt(pow(x-a.x,2)+pow(y-a.y,2)); 27 } 28 29 node node::add(node a) { 30 return {x+a.x,y+a.y}; 31 } 32 double node::mul(node a) { 33 return x*a.x+y*a.y; 34 } 35 node node::mul(double a) { 36 return {x*a,y*a}; 37 } 38 node node::neg() { 39 return {-x,-y}; 40 } 41 42 double node::abs() { 43 return sqrt(x*x+y*y); 44 } 45 node node::unt() { 46 double d=this->abs(); 47 return {x/d,y/d}; 48 } 49 double node::agl(node a) { 50 return acos((x*a.x+y*a.y)/(this->abs()*a.abs())); 51 } 52 53 bool node::eql(node a) { 54 if(fabs(x-a.x)<1e-6&&fabs(y-a.y)<1e-6)return 1; 55 return 0; 56 } 57 int node::pal(node a) { 58 node u1=this->unt();//判断单位向量 59 node u2=a.unt(); 60 if(u1.eql(u2))return 1;//方向相同 61 if(u1.eql(u2.neg()))return -1;//方向相反 62 return 0; 63 } 64 65 double r; 66 node A,B,C,O; 67 node AB,AC,AO; 68 69 int stop() { 70 double a=B.dis(O); 71 double b=A.dis(O); 72 if(a<r||b<r)return 1; 73 double c=A.dis(B); 74 double p=(a+b+c)/2; 75 double s=sqrt(p*(p-a)*(p-b)*(p-c)); 76 if(c>a&&c>b) { 77 if(2*s/c<r)return 1; 78 return 0; 79 } 80 return 0; 81 } 82 83 int only() { 84 if(AC.pal(AB)==1)return 1; 85 return 0; 86 } 87 88 double root(double a,double b,double c) { 89 return (-b-sqrt(b*b-4*a*c))/(2*a); 90 } 91 92 void getc() { 93 double ao=A.dis(O); 94 double ac=root(1,-2*ao*cos(AC.agl(AO)),ao*ao-r*r); 95 C=A.add(AC.unt().mul(ac)); 96 } 97 98 int fun(node a,node b,node c) { 99 if(a.add(b).pal(c)==1)return 1; 100 return 0; 101 } 102 103 int jude() { 104 AB= {B.x-A.x,B.y-A.y}; 105 AO= {O.x-A.x,O.y-A.y}; 106 if(stop())return 0; 107 if(only())return 1; 108 109 getc(); 110 node CB= {B.x-C.x,B.y-C.y}; 111 node OC= {C.x-O.x,C.y-O.y}; 112 if(fun(AC.neg().unt(),CB.unt(),OC.unt()))return 1; 113 return 0; 114 } 115 int main() { 116 int T; 117 scanf("%d",&T); 118 for(int kase=1; kase<=T; kase++) { 119 scanf("%lf%lf%lf",&O.x,&O.y,&r); 120 scanf("%lf%lf%lf%lf",&A.x,&A.y,&AC.x,&AC.y); 121 scanf("%lf%lf",&B.x,&B.y); 122 printf("Case #%d: ",kase); 123 if(jude())printf("Yes\n"); 124 else printf("No\n"); 125 } 126 return 0; 127 }