zoukankan      html  css  js  c++  java
  • hrbustoj 1306:再遇攻击(计算几何,判断点是否在多边形内,水题)

    再遇攻击

    Time Limit: 1000 MS    Memory Limit: 65536 K

    Total Submit: 253(37 users)   Total Accepted: 56(29 users)       Rating:         Special Judge: No

    Description

    Dota中英雄技能攻击会有一个范围,现在释放一个技能给出他的攻击范围和目标英雄的位置,问是否能攻击到。攻击范围保证是一个多边型。

    Input

    有多组测试数据

     

    第一行输入1个整数n, 期中n代表攻击范围是给出的n个点组成的多边形,按照时针方向(顺或逆)依次给出,(n>=3)N = 0输入结束。

     

    第二行a,b表示目标英雄的坐标( 0 < a,b<100)

     

    接下来有n行,每行两个整数x,y(0 < x,y <100)表示每个点的坐标

     

    攻击范围在边缘也算在内

     

    Output

    每组结果输出占一行

     

    如果能够攻击到输出”Yes”

     

    否则输出”No”

     

    Sample Input

    3

    1 1

    4 4

    5 4

    4 6

    0

     

    Sample Output

    No

    Author

    鲁学涛


      计算几何,判断点是否在多边形内

      水题,没有什么需要注意的地方。

      代码:

     1 #include <stdio.h>
     2 struct Point{
     3     double x,y;
     4 };
     5 struct Line{
     6     Point p1,p2;
     7 };
     8 double xmulti(Point p1,Point p2,Point p0)    //求p1p0和p2p0的叉积,如果大于0,则p1在p2的顺时针方向
     9 {
    10     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    11 }
    12 double Max(double a,double b)
    13 {
    14     return a>b?a:b;
    15 }
    16 double Min(double a,double b)
    17 {
    18     return a<b?a:b;
    19 }
    20 bool ponls(Point q,Line l)    //判断点q是否在线段l上
    21 {
    22     if(q.x > Max(l.p1.x,l.p2.x) || q.x < Min(l.p1.x,l.p2.x)
    23         || q.y > Max(l.p1.y,l.p2.y) || q.y < Min(l.p1.y,l.p2.y) )
    24         return false;
    25     if(xmulti(l.p1,l.p2,q)==0)    //点q不在l的延长线或者反向延长线上,如果叉积再为0,则确定点q在线段l上
    26         return true;
    27     else
    28         return false;
    29 }
    30 bool pinplg(int pointnum,Point p[],Point q)
    31 {
    32     Line s;
    33     int c = 0;
    34     for(int i=1;i<=pointnum;i++){    //多边形的每条边s
    35         if(i==pointnum)
    36             s.p1 = p[pointnum],s.p2 = p[1];
    37         else
    38             s.p1 = p[i],s.p2 = p[i+1];
    39         if(ponls(q,s))    //点q在边s上
    40             return true;
    41         if(s.p1.y != s.p2.y){    //s不是水平的
    42             Point t;
    43             t.x = q.x - 1,t.y = q.y;
    44             if( (s.p1.y == q.y && s.p1.x <=q.x) || (s.p2.y == q.y && s.p2.x <= q.x) ){    //s的一个端点在L上
    45                 int tt;
    46                 if(s.p1.y == q.y)
    47                     tt = 1;
    48                 else if(s.p2.y == q.y)
    49                     tt = 2;
    50                 int maxx;
    51                 if(s.p1.y > s.p2.y)
    52                     maxx = 1;
    53                 else
    54                     maxx = 2;
    55                 if(tt == maxx) //如果这个端点的纵坐标较大的那个端点
    56                     c++;
    57             }
    58             else if(xmulti(s.p1,t,q)*xmulti(s.p2,t,q) <= 0){    //L和边s相交
    59                 Point lowp,higp;
    60                 if(s.p1.y > s.p2.y)
    61                     lowp.x = s.p2.x,lowp.y = s.p2.y,higp.x = s.p1.x,higp.y = s.p1.y;
    62                 else
    63                     lowp.x = s.p1.x,lowp.y = s.p1.y,higp.x = s.p2.x,higp.y = s.p2.y;
    64                 if(xmulti(q,higp,lowp)>=0)
    65                     c++;
    66             }
    67         }
    68     }
    69     if(c%2==0)
    70         return false;
    71     else
    72         return true;
    73 }
    74 int main()
    75 {
    76     int i,n;
    77     while(scanf("%d",&n)!=EOF){
    78         if(n==0) break;
    79         Point t;
    80         scanf("%lf%lf",&t.x,&t.y);
    81         Point p[101];
    82         for(i=1;i<=n;i++)    //输入多边形的顶点
    83         scanf("%lf%lf",&p[i].x,&p[i].y);
    84         if(pinplg(n,p,t))
    85             printf("Yes
    ");
    86         else
    87             printf("No
    ");
    88     }
    89     return 0;
    90 }

    Freecode : www.cnblogs.com/yym2013

  • 相关阅读:
    转:五年java人的一点感悟
    6:ZigZag Conversion
    5:Longest Palindromic Substring
    4:Median of Two Sorted Arrays
    3:Longest Substring Without Repeating Characters
    读写分离
    docker swarm部署spring cloud服务
    kubeadm方式安装kubernetes
    《Spring Boot 实战》随记
    https部署
  • 原文地址:https://www.cnblogs.com/yym2013/p/3650694.html
Copyright © 2011-2022 走看看