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 }
View Code

 

你可能感兴趣的:(ACM 2015年上海区域赛A题 HDU 5572An Easy Physics Problem)