• Gym 102219H-Are You Safe?(凸包求解+判断点与凸包关系)


    题目链接:https://codeforces.com/gym/102219/problem/H
    博客园食用链接:https://blog.csdn.net/qq_43906000/article/details/107884811

    Recently, the nation was shocked by news of Sungai Kim Kim incident in Pasir Gudang, Johor, which has been polluted by chemical waste. Thousands of people who are affected had experienced nausea, dizziness and vomiting, and more than 100 schools were ordered to shut. In order to ensure that such incident will not happen again, an early warning system need o be developed so that residents can make early preparation, and authorities are able to move and act much faster.

    A group of scientists has formed a committee to handle the incident, and a smart system with Internet of Things (IoT) sensors was suggested. Numerous sensors which can sense and monitor damages to the environment, either air or water, have been strategically installed around the state, and their coordinates are also recorded. However, the proposed system encountered a failure during its first testing phase. They want you to fix the problem in determining whether the given coordinates of sensors are safe or in the affected areas.

    An affected area is defined as the polygon with the minimum length perimeter that can enclose all sensors that trigger warning signal within that area. For example, the sensors (represented by dots) of an affected area and its associated polygon, as well as safe (represented by triangles) and unsafe (represented by diamonds) points of the first dataset are illustrated below.


    Input
    The input will contain records of data for several test cases of affected areas. The first line of each data set contains a non-negative integer T, the number of test cases ((1≤T≤50)). Each test case starts with two non-negative integer C and P which is the number of coordinates ((3≤C≤50)), and points ((1≤P≤50)), respectively. The next C lines contain coordinates (x-coordinate, y-coordinate) of each installed sensor, separated with blank spaces. The following P lines contain coordinates (x-coordinate, y-coordinate) of certain locations in the state, separated with blank spaces. All coordinates are integers between −500 and 500 inclusive.

    Output
    For each test case, output the following item:

    First line: The number of the test cases. The first record corresponds to Case1, the second to Case2 , etc.

    Next line: A listing of all the points that appear on the perimeter of the affected area. The points must be identified in the standard form "x-coordinate y- coordinate". The listing must be oriented counter-clockwise and begin and end with the same point.

    Last line: For each point of location in the data set, output the line:

    x−coordinatey−coordinateisstatus
    where x−coordinatey−coordinate is the coordinate of the location from the input and status is ′safe′ or ′unsafe′. A location is considered unsafe it is within the sensor perimeter. A point in exactly at the edge of the perimeter is considered safe.

    Each test case must be separated by an empty line. See example.

    Example
    Input
    2
    6 5
    -477 -180
    31 -266
    -474 28
    147 49
    323 -53
    277 -79
    346 488
    -139 -183
    -427 129
    386 -222
    -408 -315
    5 2
    -52 -325
    104 420
    315 356
    -192 8
    493 146
    404 228
    -239 484

    Output
    Case 1
    -477 -180
    31 -266
    323 -53
    147 49
    -474 28
    -477 -180
    346 488 is safe!
    -139 -183 is unsafe!
    -427 129 is safe!
    386 -222 is safe!
    -408 -315 is safe!

    Case 2
    -192 8
    -52 -325
    493 146
    315 356
    104 420
    -192 8
    404 228 is unsafe!
    -239 484 is safe!

    题目大意:给你n个点,你现在要从其中选择一些点构成一个凸包,再给你m个点,判断是否再凸包内,如果不在,则输出(x y is safe!)否则输出(x y is unsafe!),注意当点再边上的时候也认为他们是安全的,凸包的输出要求逆时针方向且首位相接。

    emmm,就是个裸的板子题。。。要是早点套一下zzq的板子就好了,网上的一堆板子全都WA1。。。。。好像用整形写也是WA1,用double好像就过了。。。

    套一下求凸包的板子,这个可以不要考虑顺序的,反正最后你控制一些输出顺序就好了,至于判断点是否再凸包内,这50的数据范围量,随便写都OK,写个(O(n))的都可以,不过大多数的人手中可能都只有(O(logn))的板子,也没什么可说的了,就是个板子模块

    以下是AC代码:

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    
    typedef long long ll;
    const int MAXN = 1e3+10;
    const double esp=1e-8;
    
    struct Point {
        double x,y;
        Point(double x_ = 0, double y_ = 0) : x(x_), y(y_) {}
        bool operator < (const Point& s) const {
            return x != s.x ? x < s.x : y < s.y;
        }
        Point operator - (const Point &A) const{
            return Point{x-A.x,y-A.y};
        }
    } p[MAXN], ch[MAXN];
    
    int dcmp(double x) { //返回x的正负
        if (fabs(x)<esp) return 0;
        return x<0?-1:1;
    }
    
    double Cross(Point A,Point B) { //叉积
        return A.x*B.y-A.y*B.x;//如果改成整形记得加LL
    }
    
    int Graham(Point *P,Point *R,int n) {
        int m = 0, k;
        sort(P, P + n);
        for(int i = 0; i < n; i++) {
            while(m > 1 && dcmp(Cross(R[m - 1]-R[m-2],P[i]-R[m - 2]))<= 0) m--;
            R[m++] = P[i];
        }
        k = m;
        for(int i = n - 2; i >= 0; i--) {
            while(m > k && dcmp(Cross(R[m - 1]-R[m-2],P[i]-R[m - 2]))<= 0) m--;
            R[m++] = P[i];
        }
        if(n > 1) m--;
        return m;
    }
    
    int n,m;
    Point use[MAXN];
    
    int IsPointInPolygon(Point P,Point *R){   //0外部,-1在边上,1在内部
        int l=1, r=n-2,mid;
        while(l<=r){
            mid = (l+r) >> 1;
            int t1 = dcmp(Cross(R[mid]-R[0],P-R[0]));
            int t2 = dcmp(Cross(R[mid+1]-R[0],P-R[0]));
            if(t1>=0 &&t2<=0){
                int t3=dcmp(Cross(R[mid]-P,R[mid+1]-P));
                if(t3 < 0) return 0;
                else if((t1==0&&mid==1)||(t2==0&&mid+1==n-1)||t3==0)return -1;
                return 1;
            }
            else if(t1 < 0)r = mid -1;
            else l = mid+1;
        }
        return 0;
    }
    
    int main() {
        //freopen("in.txt","r",stdin);
        int T;
        scanf ("%d",&T);
        for (int cae=1; cae<=T; cae++) {
            scanf ("%d%d",&n,&m);
            for (int i=0; i<n; i++)
                scanf ("%lf%lf",&p[i].x, &p[i].y);
            for (int i=1; i<=m; i++)
                scanf ("%lf%lf",&use[i].x, &use[i].y);
            n = Graham(p, ch, n);
           // n--;
            printf("Case %d
    ",cae);
            for (int i = 0; i < n; i++)
                printf("%.0f %.0f
    ", ch[i].x, ch[i].y);
            printf("%.0f %.0f
    ",ch[0].x,ch[0].y);
    
            for (int i=1; i<=m; i++){
                printf("%.0f %.0f is ",use[i].x,use[i].y);
                int ok=IsPointInPolygon(use[i],ch);
                if (ok==1) printf("unsafe!
    ");
                else printf("safe!
    ");
            }
            if (cae!=T) printf("
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    BZOJ1027 [HNOI2004]打鼹鼠 【dp】
    面试的绝招(V1.0)
    面试的绝招(V1.0)
    Google是如何做测试的?
    Google是如何做测试的?
    Google是如何做测试的?
    六年测试之精华分享:产品质量应从哪些方面提高
    六年测试之精华分享:产品质量应从哪些方面提高
    六年测试之精华分享:产品质量应从哪些方面提高
    拒绝混乱,回归有序
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13460130.html
Copyright © 2020-2023  润新知