zoukankan      html  css  js  c++  java
  • XMU 1071 圣斗士黄金十二宫(七)银河星爆 【计算几何】

    1071: 圣斗士黄金十二宫(七)银河星爆

    Time Limit: 500 MS  Memory Limit: 64 MB
    Submit: 193  Solved: 10
    [Submit][Status][Web Board]

    Description

      撒加回答了星矢的第一个问题,但是当星矢要问第二个问题时,撒加的头发全变白了。白撒加的实力是无人能及的,星矢被废去了五感。这时帮沙加统计完单词的一辉也赶到了,想打赢白撒加是不可能的,一辉的目标就是争取时间让星矢拿到铜盾。为了尽快打倒被称为不死鸟的一辉,撒加也使出生平绝技---即使是星星被击中也要粉碎的银河星爆。
    从撒加放出银河星爆到银河星爆接近一辉需要一段时间,在这段时间里一辉可以朝任何方向移动k单位的距离来躲开银河星爆。银河星爆的横截面为一个圆形,显然一辉在与横截面平行的平面上移动可以以最大的概率躲过。在该平面上建立直角坐标系横轴为x纵轴为y,银河星爆的横截面圆心坐标为(x1, y1),半径为R1。
    把一辉也当成一个圆,他在坐标系上朝任意方向移动的最大距离为k,考虑到地形因素和一辉个人能力,一辉所能移动到的点(x , y)需满足0 <= x <= 1000 , 0 <= y <= 1000。如果两个圆不相交则说明一辉躲过了银河星爆(注意两圆外切也说明一辉躲过了)。
    现在请您预测一辉能否有可能躲过撒加的银河星爆。

    Input

      第一行为三个整数x1, y1, R1,代表银河星爆的圆心坐标和半径,其中0<= x1, y1 <= 1000, 0 < R1 <= 300。
    第二行为三个整数x2, y2, R2,代表一辉的圆心坐标和半径,其中0 <= x2, y2 <= 1000, 0 < R2 <= 30。
    第三行为一个正整数k <= 2000 表示一辉可以移动的最长距离。

    Output

      如果一辉可以躲过银河星爆则输出"Yes",否则输出"No"(不包含引号)。

    Sample Input

    900 900 250
    950 950 30
    316

    Sample Output

    Yes

    HINT

     

    Source

    [Submit][Status][Web Board]

    题目链接:

      http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1071

    题目大意:

      一个炸弹,坐标(X1,Y1),爆炸半径R1,一个人,坐标(X2,Y2),视为球体半径R2,人最多移动距离为K,问能否躲过炸弹且圆心不超出边界。(外切或相离)

    题目思路:

      【计算几何】

      首先将人的体积半径算在爆炸范围内,即R1=R1+R2。人的运动范围也为一个圆R2=K。这样确定了两个圆。

      分情况考虑,在不超界的情况下,如果相离或相切(圆心距离>=半径和)则可行。

      如果相交,则优先考虑按圆心连线的方向逃离是否可行,是否超界。

      若超界则求圆的交点,若交点有一个在边界内则可行。

      内含不可行。

      1 /****************************************************
      2 
      3     Author : Coolxxx
      4     Copyright 2017 by Coolxxx. All rights reserved.
      5     BLOG : http://blog.csdn.net/u010568270
      6 
      7 ****************************************************/
      8 #include<bits/stdc++.h>
      9 #pragma comment(linker,"/STACK:1024000000,1024000000")
     10 #define abs(a) ((a)>0?(a):(-(a)))
     11 #define lowbit(a) (a&(-a))
     12 #define sqr(a) ((a)*(a))
     13 #define mem(a,b) memset(a,b,sizeof(a))
     14 const double EPS=0.00001;
     15 const int J=10;
     16 const int MOD=100000007;
     17 const int MAX=0x7f7f7f7f;
     18 const double PI=3.14159265358979323;
     19 const int N=124;
     20 using namespace std;
     21 typedef long long LL;
     22 double anss;
     23 LL aans;
     24 int cas,cass;
     25 int n,m,lll,ans;
     26 
     27 struct Point
     28 {
     29     double x, y;
     30     Point(double x = 0, double y = 0) :x(x), y(y) {}
     31 };
     32 
     33 typedef Point Vector;
     34 
     35 Vector operator - (Point A, Point B)
     36 {
     37     return Vector(A.x - B.x, A.y - B.y);
     38 }
     39 
     40 Vector operator + (Vector A, Vector B)
     41 {
     42     return Vector(A.x + B.x, A.y + B.y);
     43 }
     44 
     45 Vector operator * (Vector A, double p)
     46 {
     47     return Vector(A.x * p, A.y * p);
     48 }
     49 
     50 Vector operator / (Vector A, double p)
     51 {
     52     return Vector(A.x / p, A.y / p);
     53 }
     54 
     55 double Dot(Vector A,Vector B)
     56 {
     57     return A.x * B.x + A.y * B.y;
     58 }
     59 
     60 double Length(Vector A)
     61 {
     62     return sqrt(Dot(A,A));
     63 }
     64 
     65 double Angle(Vector A,Vector B)  //求角度
     66 {
     67     return acos(Dot(A,B) / Length(A) / Length(B));
     68 }
     69 
     70 double angle(Vector v)
     71 {
     72     return atan2(v.y,v.x);
     73 }
     74 
     75 const double eps = 1e-10;
     76 int dcmp(double x)
     77 {
     78     if(fabs(x) < eps) return 0;
     79     else
     80         return x < 0 ? -1 : 1;
     81 }
     82 
     83 bool operator < (const Point& a,const Point& b)
     84 {
     85     return a.x < b.x || (a.x == b.x && a.y < b.y);
     86 }
     87 
     88 bool operator == (const Point& a,const Point &b)
     89 {
     90     return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
     91 }
     92 
     93 struct Circle
     94 {
     95     Point c;
     96     double r;
     97     Circle(Point c, double r) :c(c), r(r) {}
     98     Point point(double a)
     99     {
    100         return Point(c.x + cos(a) * r, c.y + sin(a) * r);
    101     }
    102 };
    103 
    104 int getCircleCircleIntersection(Circle C1,Circle C2,vector<Point>& sol)  //求圆和圆的交点
    105 {
    106     double d = Length(C1.c - C2.c);
    107     if(dcmp(d) == 0)   //首先圆心要重合
    108     {
    109         if(dcmp(C1.r - C2.r) == 0) return -1; //其次半径要相同,然后就可以推出两圆重合
    110         return 0;
    111     }
    112     if(dcmp(C1.r + C2.r - d) < 0) return 0; //相离没交点
    113     if(dcmp(fabs(C1.r - C2.r) - d) > 0) return 0; //圆在圆中,没有交点
    114 
    115     double a = angle(C2.c - C1.c); //向量C1C2的极角
    116     double da = acos((C1.r * C1.r + d * d - C2.r * C2.r) / (2 * C1.r * d)); //C1C2到C1P1的角
    117     Point p1 = C1.point(a-da),p2 = C1.point(a+da);
    118 
    119     sol.push_back(p1);
    120     if(p1 == p2) return 1; //相切
    121     sol.push_back(p2);
    122     return 2; //相交
    123 }
    124 inline bool inside(double x,double y)
    125 {
    126     return (x>=0 && x<=1000 && y>=0 && y<=1000);
    127 }
    128 int main()
    129 {
    130     #ifndef ONLINE_JUDGE
    131     freopen("test10.in","r",stdin);
    132 //    freopen("1.txt","w",stdout);
    133     #endif
    134     int i,j,k;
    135     double x,y,z;
    136     double xx,yy,zz;
    137 //    for(scanf("%d",&cass);cass;cass--)
    138 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
    139 //    while(~scanf("%s",s))
    140     while(cin>>x>>y>>z)
    141     {
    142         cin>>xx>>yy>>zz>>k;
    143         Circle c1(Point(x,y),z+zz),c2(Point(xx,yy),k);
    144         
    145         if(dcmp(sqr(xx-x)+sqr(yy-y)-sqr(z+zz))>0)
    146         {
    147             puts("Yes");
    148             continue;
    149         }
    150         vector<Point>a;
    151         vector<Point>::iterator iter;
    152         while(!a.empty())a.pop_back();
    153         z=getCircleCircleIntersection(c1,c2,a);
    154         if(z == -1)
    155         {
    156             puts("Yes");
    157         }
    158         else if(z == 0)
    159         {
    160             double d = Length(c1.c - c2.c);
    161             if(dcmp(d) == 0)   //首先圆心要重合
    162             {
    163                 if(dcmp(c1.r - c2.r) < 0)puts("Yes");
    164                 else puts("No");
    165             }
    166             else if(dcmp(c1.r + c2.r - d) < 0)puts("Yes");//相离没交点
    167             else if(dcmp(c2.r - c1.r - d) > 0)puts("Yes");//圆在圆中,没有交点
    168             else puts("No");
    169         }
    170         else if(z == 1)
    171         {
    172             iter = a.begin();
    173             x = iter->x;
    174             y = iter->y;
    175             if(inside(x,y))puts("Yes");
    176             else puts("No");
    177         }
    178         else
    179         {
    180             x=c1.c.x+(c2.c.x-c1.c.x)*c1.r/(Length(c1.c-c2.c));
    181             y=c1.c.y+(c2.c.y-c1.c.y)*c1.r/(Length(c1.c-c2.c));
    182             if(sqr(x-c2.c.x)+sqr(y-c2.c.y)<=k*k && inside(x,y))
    183             {puts("Yes");continue;}
    184             
    185             iter = a.begin();
    186             x = iter->x;
    187             y = iter->y;
    188             iter++;
    189             xx = iter->x;
    190             yy = iter->y;
    191             if(inside(x,y) || inside(xx,yy))
    192                 puts("Yes");
    193             else puts("No");
    194         }
    195     }
    196     return 0;
    197 }
    198 /*
    199 //
    200 
    201 //
    202 */
    View Code
  • 相关阅读:
    MySQL数据库之索引
    python面向对象编程
    linux端口占用
    lintcode
    java基础
    lintcode
    linux 常用命令
    Docker & Kubernates
    angular preparation
    java 命令行
  • 原文地址:https://www.cnblogs.com/Coolxxx/p/7065350.html
Copyright © 2011-2022 走看看