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
  • 相关阅读:
    iOS 基础类解析
    冒泡排序Vs直接选择排序
    【HDOJ 5419】 Victor and Toys (排列组合)
    我的互联网安全观
    Linux进程间通信-信号量
    AFNetworking 3.0携带參数上传文件Demo
    ANDROID窗体管理服务实现机制和架构分析
    【ODPS】阿里云ODPS中带分区的表操作
    Android自定义组件系列【13】——Android自定义对话框如此简单
    微信支付开发(2) 静态链接Native支付
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4129807.html
Copyright © 2011-2022 走看看