zoukankan      html  css  js  c++  java
  • Light oj 1190

    Time Limit: 2 second(s) Memory Limit: 32 MB

    All of you know about "Alauddin vai". But what you don't know is, he sometimes walks while sleeping. Yes, some kind of sleep walking.

    Now one day he was sleeping in a strange room. But after waking up he doubts that whether he is inside the room or not.

     

    You may assume that the room can be modeled as a polygon whose coordinates are 2D integer points. Alauddin vai can be thought as a 2D integer point. Now you are given the configuration of the room and the position of Alauddin vai (after waking up). You have to decide whether he is still in the room or not. Consider him inside if he is on the boundary of the polygon.

    Input

    Input starts with an integer T (≤ 10), denoting the number of test cases.

    Each case starts with an integer n (3 ≤ n ≤ 100) denoting the number of vertices of the room. The next line contains 2n integers, where the ith pair xi yi denote the co-ordinate of the ith vertex of the room. The vertices will be given in anticlockwise order. The next line contains an integer q (1 ≤ q ≤ 300) denoting the number of queries. Each of the next qlines contains two integers x y denoting the co-ordinate of Alauddin vai. The absolute value of the given co-ordinates will be less than 10001.

    Output

    For each case, print the case number in a single line. Then print q lines, containing the answer for the queries as given in input. Print 'Yes' if he is inside the room, print 'No' otherwise.

    Sample Input

    Output for Sample Input

    2

    3

    0 0 10 0 0 20

    2

    5 5

    10 10

    3

    0 0 3 3 0 3

    1

    5 5

    Case 1:

    Yes

    No

    Case 2:

    No

    分析: 1,如果点在多边形顶点或者在多边形边上,则认为点在多边形内部(很容易判断)

        2,点不在多边形边上和顶点上,如图所示:

    则只要在多边形外部随便找一个端点和已知点组成一个线段,判断此线段与多边形边数相交个数为奇偶即可。奇数在内部,偶数在外部。

    有些人会说,随便找的这个线段会经过端点呀,就没法判断了。如下图:

    那我告诉你,你找一个线段不经过端点不就行了。这个随便找也不是那么“随便”的。怎么样不经过多边形端点呢?

    题目说数据范围在10001以内,并且都是整数(这个很重要,非常重要)。我只需要让这个线段在数据范围以内不经过整数端点即可。

    比如我“随便”在多边形外部找一个坐标点(1111111,1111135)

    如果你随便找的点不行,那就多“随便”找几个

    上代码:

    #include <stdio.h>
    #include <cstring>
    #include <math.h>
    #include <iostream>
    #include <set>
    #include <queue>
    #include <algorithm>
    using namespace std;
    #define LL long long
    #define INF 0x3f3f3f3f
    #define PI acos(-1)
    struct Point
    {
        double x,y;
        Point(double x=0,double y=0):x(x),y(y){}
    }p[105],q[3];
    typedef Point Vector;
    Vector operator -(Point A, Point B)
    {
        return Vector(A.x-B.x, A.y-B.y);
    }
    double Cross(Vector A, Vector B)
    {
        return A.x*B.y-A.y*B.x;
    }
    int in(double x1, double y1,int n)
    {
        for(int i=0; i<n; i++)
        {
            if(fabs(p[i].x-x1)<=1e-8&&fabs(p[i].y-y1)<=1e-8)
                return 1;
        }
        for(int i=0; i<=n; i++)
        {
            Point a;
            a.x=x1;a.y=y1;
            if(x1>=min(p[i].x,p[i+1].x)&&y1>=min(p[i].y,p[i+1].y)
               &&x1<=max(p[i].x,p[i+1].x)&&y1<=max(p[i].y,p[i+1].y)
               &&fabs(Cross(p[i+1]-a,a-p[i]))<=1e-8)
                return 1;
        }
        return 0;
    }
    int main()
    {
        int T,t=1,n,m;
        double x1,y1;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            for(int i=0; i<n; i++)
                scanf("%lf%lf", &p[i].x, &p[i].y);
            p[n]=p[0];
            scanf("%d", &m);
            printf("Case %d:
    ", t++);
            for(int i=0; i<m; i++)
            {
                scanf("%lf%lf", &q[0].x, &q[0].y);
                if(in(q[0].x,q[0].y,n)==1)///判断点在多边形上
                {
                    printf("Yes
    ");
                    continue;
                }
                q[1].x=1111111;q[1].y=1111135;
                int sum=0;///记录射线与多边形“边”的交点
                for(int j=0; j<n; j++)
                {
                    if(Cross(q[1]-q[0],p[j]-q[0])*Cross(q[1]-q[0],p[j+1]-q[0])<0
                       &&Cross(p[j+1]-p[j],q[1]-p[j])*Cross(p[j+1]-p[j],q[0]-p[j])<0
                       &&max(q[0].x,q[1].x)>=min(p[j].x,p[j+1].x)
                       &&max(q[0].y,q[1].y)>=min(p[j].y,p[j+1].y)
                       &&max(p[j].x,p[j+1].x)>=min(q[0].x,q[1].x)
                       &&max(p[j].y,p[j+1].y)>=min(q[0].y,q[1].y))
                        sum++;
                }
                if(sum%2!=0)
                    printf("Yes
    ");
                else
                    printf("No
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    wifi通信过程的研究--(2)Wifi传输认证过程
    wifi通信过程的研究--(1)Wifi基本属性介绍
    wifi通信过程的研究--(3)传输过程概念细分
    网络编程之TCP/IP各层详解
    持续集成CI与自动化构建
    IEEE 802.11标准列表
    IEEE802.11协议基础知识
    IEEE 802.11协议基础知识整理
    beacon帧字段结构最全总结(三)——VHT字段总结
    beacon帧字段结构最全总结(二)——HT字段总结
  • 原文地址:https://www.cnblogs.com/zhulei2/p/9993459.html
Copyright © 2011-2022 走看看