首页 > 代码库 > HDU 4793 Collision(2013长沙区域赛现场赛C题)

HDU 4793 Collision(2013长沙区域赛现场赛C题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4793

解题报告:在一个平面上有一个圆形medal,半径为Rm,圆心为(0,0),同时有一个圆形范围圆心也是(0,0),半径为R,R > Rm,现在向平面上投掷一枚硬币,硬币初始的圆心位置为(x,y),半径是r,给出硬币的速度向量,硬币碰到medal的时候会反射,注意,反射就是原路返回,并不是按照常理的按照圆心连线的路线,表示一直以为是这样,WA了很久,然后,让你求硬币跟圆形范围有交集的时候的总时间是多少。

首先,过原点,作一条与速度向量平行的直线l,然后求出(x,y)到直线l的距离D,然后通过一系列勾股定理就可以求出路程。值得注意的就是有几种情况要特判。

第一,速度的方向跟(x,y)与原点的连线的向量的夹角是不是[0,90)的范围,然后满足这个条件之后还要判断,当D > R+r时,硬币会直接过去而不会经过圆形范围,所以时间直接是0,当Rm+r < D < R+r时,硬币会经过圆形范围,但不会跟medal有碰撞,当D < Rm+r时,硬币跟medal有碰撞。

 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const double eps = 1e-8,PI = acos(-1.0); 8  9 struct point10 {11     double x,y;12     point(double x = 0,double y = 0) :x(x),y(y){}13     double len()14     {15         return sqrt(x*x+y*y+eps);16     }17 };18 inline double dis(point p1,point p2)19 {20     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+eps);21 }22 double get_dis(point v,point p)23 {24     if(fabs(v.x*p.y - p.x*v.y) < eps) return 0;25     double si = (v.x*p.y-p.x*v.y)/dis(point(0,0),v)/p.len();26     return p.len() * fabs(si);27 }28 int judge(point p,point v)29 {30     point temp;31     temp.x = -1 * p.x;32     temp.y = -1 * p.y;33     return (temp.x*v.x+temp.y*v.y < 0) || (fabs(temp.x*v.x+temp.y*v.y) <eps);34 }35 int main()36 {37 //    freopen("in.txt","r",stdin);38     double Rm,R,r;39     point p,v;40     while(scanf("%lf%lf%lf%lf%lf%lf%lf",&Rm,&R,&r,&p.x,&p.y,&v.x,&v.y)!=EOF)41     {42         if(judge(p,v))43         {44             printf("0.0000\n");45             continue;46         }47         double V = v.len();48         double D = get_dis(v,p);     //得到硬币到过原点的运动路线的距离49 //        printf("%.3lf\n",D);50         double ans = 0;51         if(D < Rm+r)    //会碰撞,坑,这种情况下题目的反射违反了常理,一直wa在这里 52         {53             double l = sqrt((R+r)*(R+r)-D*D+eps) - sqrt((Rm+r)*(Rm+r)-D*D+eps);  //进入圈开始到碰撞走过的距离54             ans += (l / V);55         //    ans += (R - Rm) / V;56         }57         else if(D > Rm+r && D < R + r)58         {59             double t = sqrt((R+r)*(R+r) - D*D+eps) / V;60         }61         else     //不会进入圆形范围 62         {63             printf("0.00000\n");64             continue;65         } 66         printf("%lf\n",2*ans+eps);67     }68     return 0;69 }        
View Code

 

HDU 4793 Collision(2013长沙区域赛现场赛C题)