zoukankan      html  css  js  c++  java
  • hlg1306再遇攻击--射线法判断点是否在多边形内部

    再遇攻击
    Time Limit: 1000 MS Memory Limit: 65536 K
    Total Submit: 313(40 users) Total Accepted: 91(32 users) Rating:  Special Judge: No
    Description
    Dota中英雄技能攻击会有一个范围,现在释放一个技能给出他的攻击范围和目标英雄的位置,问是否能攻击到。攻击范围保证是一个多边型。
    Input

    有多组测试数据

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

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

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

    攻击范围在边缘也算在内

    Output

    每组结果输出占一行

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

    否则输出”No”

    Sample Input

    3

    1 1

    4 4

    5 4

    4 6
    0

    Sample Output
    No
    Author
    鲁学涛
     

    夜很静

    静谧的有点让人享受……

    其实我是在装深沉,噢哈哈哈哈哈哈

    O(∩_∩)O~~

    题目就是判断一个点是否在一个多边形内部,很简单吧==

    戴某

    本人却错的异常惨烈,

    本人先用二分做了一下,

    oj以一记wrong让我明白了一个惨痛的真理

    二分只能用于判断凸四边形==

    ==============================

    下面不扯了

    介绍下今天学到的新方法

    射线法

    就是从查询点向任意方向引出一条射线看脚垫的个数

    奇数个说明在内部‘

    偶数个则在外部

    很好实现吧~~

    我是有多笨~~这么久简单的几行代码费了这么大劲,哎==

    yaokaol的细节总结来就三点:
    一、 对于点在某边上 则直接返回 true

    二、对于平行的边则不予以考虑(这点让我理解了好久==智商捉急===)

    三、对于每条边只考虑上顶点 忽略下定点(====)

    只要注意到这三点代码就很容易实现了~~

    附一下伪代码:(这位童鞋的伪代码让人眼前一亮)

    上图伪代码要把判断点是否在slid上放在判断平行之前,

    代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 
     7 const int maxn = 55;
     8 
     9 int min(int a, int b)
    10 {
    11     return a > b ? b : a;
    12 }
    13 int max(int a, int b)
    14 {
    15     return a > b ? a : b;
    16 }
    17 
    18 struct point
    19 {
    20     int x;
    21     int y;
    22 }poin[maxn];
    23 
    24 int cross(point p0, point p1, point p2)
    25 {
    26     return (p1.x - p0.x)*(p2.y - p0.y) - (p2.x - p0.x)*(p1.y - p0.y);
    27 }
    28 
    29 bool check_online(point p1, point p2, point Q)
    30 {
    31     if(cross(p1, Q, p2) == 0 &&
    32        Q.x >= min(p1.x, p2.x) && Q.x <= max(p1.x, p2.x) &&
    33        Q.y >= min(p1.y, p2.y) && Q.y <= max(p1.y, p2.y) )
    34         return true;
    35     return false;
    36 }
    37 
    38 bool check_two_line(point a,point b, point c, point d)
    39 {
    40     int h, i, j, k;
    41     h = cross(a, b, c);
    42     i = cross(a, b, d);
    43     j = cross(c, d, a);
    44     k = cross(c, d, b);
    45     return h * i <= 0 && j * k <= 0;
    46 }
    47 
    48 int main()
    49 {
    50     int n;
    51     while(scanf("%d",&n) && n)
    52     {
    53         point Q, P, p1, p2;
    54         scanf("%d %d",&Q.x, &Q.y);
    55         P.x = 101, P.y = Q.y;
    56         for(int i = 0; i < n; i++)
    57             scanf("%d %d",&poin[i].x, &poin[i].y);
    58         bool flag = false;
    59         int cnt = 0;
    60         for(int i = 0; i < n; i++)
    61         {
    62             p1 = poin[i], p2 = poin[(i+1)%n];
    63             if(check_online(p1, p2, Q))
    64             {
    65                 flag = true;
    66                 break;
    67             }
    68             if(p1.y == p2.y)
    69                 continue;
    70             if(Q.y > min(p1.y, p2.y) && Q.y <= max(p1.y, p2.y))
    71             {
    72                 if(check_two_line(Q, P, p1, p2))
    73                     cnt++;
    74             }
    75         }
    76         //printf("%d
    ",cnt);
    77         if(flag)
    78         {
    79             printf("Yes
    ");
    80             continue;
    81         }
    82         if(cnt % 2 == 1)
    83             printf("Yes
    ");
    84         else
    85             printf("No
    ");
    86     }
    87     return 0;
    88 }
    View Code
  • 相关阅读:
    桂林游览3
    其实她们也是屌丝,但2的好像只有我。。。
    屌丝吖
    我觉得拍照这丫头狠有天赋
    《那些年啊,那些事——一个程序员的奋斗史》——56
    《那些年啊,那些事——一个程序员的奋斗史》——57
    《那些年啊,那些事——一个程序员的奋斗史》——57
    《那些年啊,那些事——一个程序员的奋斗史》——56
    《那些年啊,那些事——一个程序员的奋斗史》——59
    《那些年啊,那些事——一个程序员的奋斗史》——58
  • 原文地址:https://www.cnblogs.com/zhanzhao/p/3700471.html
Copyright © 2011-2022 走看看