zoukankan      html  css  js  c++  java
  • 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 point
    10 {
    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
    ");
    45             continue;
    46         }
    47         double V = v.len();
    48         double D = get_dis(v,p);     //得到硬币到过原点的运动路线的距离
    49 //        printf("%.3lf
    ",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
    ");
    64             continue;
    65         } 
    66         printf("%lf
    ",2*ans+eps);
    67     }
    68     return 0;
    69 }        
    View Code
  • 相关阅读:
    CentOS虚拟机和物理机共享文件夹实现
    集训第六周 数学概念与方法 概率 数论 最大公约数 G题
    集训第六周 数学概念与方法 概率 F题
    集训第六周 E题
    集训第六周 古典概型 期望 D题 Discovering Gold 期望
    集训第六周 古典概型 期望 C题
    集训第六周 数学概念与方法 UVA 11181 条件概率
    集训第六周 数学概念与方法 UVA 11722 几何概型
    DAG模型(矩形嵌套)
    集训第五周 动态规划 K题 背包
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4129807.html
Copyright © 2011-2022 走看看