zoukankan      html  css  js  c++  java
  • HDU 5572--An Easy Physics Problem(射线和圆的交点)

    An Easy Physics Problem

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 3845    Accepted Submission(s): 768

    Problem Description
    On an infinite smooth table, there's a big round fixed cylinder and a little ball whose volume can be ignored.

    Currently the ball stands still at point A, then we'll give it an initial speed and a direction. If the ball hits the cylinder, it will bounce back with no energy losses.

    We're just curious about whether the ball will pass point B after some time.
     
    Input
    First line contains an integer T, which indicates the number of test cases.

    Every test case contains three lines.

    The first line contains three integers OxOy and r, indicating the center of cylinder is (Ox,Oy) and its radius is r.

    The second line contains four integers AxAyVx and Vy, indicating the coordinate of A is (Ax,Ay) and the initial direction vector is (Vx,Vy).

    The last line contains two integers Bx and By, indicating the coordinate of point B is (Bx,By).

     1 ≤ T ≤ 100.

     |Ox|,|Oy|≤ 1000. 

     1 ≤ r ≤ 100.

     |Ax|,|Ay|,|Bx|,|By|≤ 1000. 

     |Vx|,|Vy|≤ 1000.

     Vx0 or Vy0.

     both A and B are outside of the cylinder and they are not at same position.
     
     
    Output
    For every test case, you should output "Case #x: y", where x indicates the case number and counts from 1y is "Yes" if the ball will pass point B after some time, otherwise y is "No".
     
    Sample Input
    2 0 0 1 2 2 0 1 -1 -1 0 0 1 -1 2 1 -1 1 2
     
    Sample Output
    Case #1: No Case #2: Yes
     
    先判断射线和圆交点个数,如果小于2再看是否B在A的前进方向上,没有则NO,否则YES。如果等于2,就先找到第一个交点,将这个交点和圆心连成直线,那么A的路径关于这条直线对称,那么如果A关于此直线的对称点在圆心->B路径上,则可以相撞,否则不行。
    这里有一个小问题,如果反过来求B关于此直线的对称点在圆心->A路径上,是会WA的.
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include<algorithm>
      5 #include <cstdlib>
      6 #include <cmath>
      7 using namespace std;
      8 const double eps = 1e-8;
      9 int sgn(double x) {
     10     if (fabs(x) < eps)return 0;
     11     if (x < 0)return -1;
     12     else return 1;
     13 }
     14 struct point {
     15     double x, y;
     16     point() {}
     17     point(double x, double y) : x(x), y(y) {}
     18     void input() {
     19         scanf("%lf%lf", &x, &y);
     20     }
     21     bool operator ==(point b)const {
     22         return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
     23     }
     24     bool operator <(point b)const {
     25         return sgn(x - b.x) == 0 ? sgn(y - b.y)<0 : x<b.x;
     26     }
     27     point operator -(const point &b)const {        //返回减去后的新点
     28         return point(x - b.x, y - b.y);
     29     }
     30     point operator +(const point &b)const {        //返回加上后的新点
     31         return point(x + b.x, y + b.y);
     32     }
     33     point operator *(const double &k)const {    //返回相乘后的新点
     34         return point(x * k, y * k);
     35     }
     36     point operator /(const double &k)const {    //返回相除后的新点
     37         return point(x / k, y / k);
     38     }
     39     double operator ^(const point &b)const {    //叉乘
     40         return x*b.y - y*b.x;
     41     }
     42     double operator *(const point &b)const {    //点乘
     43         return x*b.x + y*b.y;
     44     }
     45     double len() {        //返回长度
     46         return hypot(x, y);
     47     }
     48     double len2() {        //返回长度的平方
     49         return x*x + y*y;
     50     }
     51     point trunc(double r) {
     52         double l = len();
     53         if (!sgn(l))return *this;
     54         r /= l;
     55         return point(x*r, y*r);
     56     }
     57 };
     58 struct line {
     59     point s;
     60     point e;
     61     line() {
     62 
     63     }
     64     line(point _s, point _e) {
     65         s = _s;
     66         e = _e;
     67     }
     68     bool operator ==(line v) {
     69         return (s == v.s) && (e == v.e);
     70     }
     71     //返回点p在直线上的投影
     72     point lineprog(point p) {
     73         return s + (((e - s)*((e - s)*(p - s))) / ((e - s).len2()));
     74     }
     75     //返回点p关于直线的对称点
     76     point symmetrypoint(point p) {
     77         point q = lineprog(p);
     78         return point(2 * q.x - p.x, 2 * q.y - p.y);
     79     }
     80     //点是否在线段上
     81     bool pointonseg(point p) {
     82         return sgn((p - s) ^ (e - s)) == 0 && sgn((p - s)*(p - e)) <= 0;
     83     }
     84 };
     85 struct circle {//
     86     double r;    //半径
     87     point p;    //圆心
     88     void input() {
     89         p.input();
     90         scanf("%lf", &r);
     91     }
     92     circle() { }
     93     circle(point _p, double _r) {
     94         p = _p;
     95         r = _r;
     96     }
     97     circle(double x, double y, double _r) {
     98         p = point(x, y);
     99         r = _r;
    100     }
    101     //求直线和圆的交点,返回交点个数
    102     int pointcrossline(line l, point &r1, point &r2) {
    103         double dx = l.e.x - l.s.x, dy = l.e.y - l.s.y;
    104         double A = dx*dx + dy*dy;
    105         double B = 2 * dx * (l.s.x - p.x) + 2 * dy * (l.s.y - p.y);
    106         double C = (l.s.x - p.x)*(l.s.x - p.x) + (l.s.y - p.y)*(l.s.y - p.y) - r*r;
    107         double del = B*B - 4 * A * C;
    108         if (sgn(del) < 0)  return 0;
    109         int cnt = 0;
    110         double t1 = (-B - sqrt(del)) / (2 * A);
    111         double t2 = (-B + sqrt(del)) / (2 * A);
    112         if (sgn(t1) >= 0) {
    113             r1 = point(l.s.x + t1 * dx, l.s.y + t1 * dy);
    114             cnt++;
    115         }
    116         if (sgn(t2) >= 0) {
    117             r2 = point(l.s.x + t2 * dx, l.s.y + t2 * dy);
    118             cnt++;
    119         }
    120         return cnt;
    121     }
    122 };
    123 point A, V, B;
    124 circle tc;
    125 point r1, r2;
    126 int main() {
    127     int t, d = 1;
    128     scanf("%d", &t);
    129     while (t--) {
    130         tc.input();
    131         A.input();
    132         V.input();
    133         B.input();
    134         int f = 0;
    135         int num = tc.pointcrossline(line(A, A + V), r1, r2);
    136         if (num < 2) {
    137             point t = B - A;
    138             if (t.trunc(1) == V.trunc(1)) f = 1;
    139             else f = 0;
    140         }
    141         else {
    142             line l = line(tc.p, r1);
    143             line l1 = line(A, r1);
    144             line l2 = line(r1, B);
    145             point t = l.symmetrypoint(A);
    146             if (l1.pointonseg(B))f = 1;
    147             else if (l2.pointonseg(t))f = 1;        //求B的对称点会WA
    148             else f = 0;
    149         }
    150         if (f == 1)
    151             printf("Case #%d: Yes
    ", d++);
    152         else
    153             printf("Case #%d: No
    ", d++);
    154     }
    155     return 0;
    156 }
    View Code
  • 相关阅读:
    # 漏洞挖掘技巧清单 #
    CVE-2020-0796——SMBV3客户端/服务端远程代码执行漏洞(远程代码执行+权限提升)
    SSH公钥详细介绍及拓展
    滑动窗口(数据结构)
    反素数解析
    树状数组的基本操作
    Rochambeau POJ
    一般图最大匹配
    2020牛客暑期多校训练营(第一场)H Minimum-cost Flow
    A Bug's Life POJ
  • 原文地址:https://www.cnblogs.com/FlyerBird/p/9741139.html
Copyright © 2011-2022 走看看