• POJ


    pro:顺时针给定多边形,问是否可以放一个监控,可以监控到所有地方,即问是否存在多边形的核。 此题如果两点在同一边界上(且没有被隔段),也可以相互看到。

    sol:求多边形是否有核。先给直线按角度排序,然后增量法即可,复杂度O(NlogN)。

    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstdio>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    using namespace std;
    const int maxn=10010;
    const double eps=1e-12;
    struct point{
        double x,y;
        point(){}
        point(double xx,double yy):x(xx),y(yy){}
    };
    struct line{
        point a;//起点
        point p;//起点到终点的向量
        double angle;
    };
    double dot(point a,point b){ return a.x*b.x+a.y*b.y;}
    double det(point a,point b){ return a.x*b.y-a.y*b.x;}
    point operator *(point A,double p){ return point(A.x*p,A.y*p);}
    point operator +(point A,point B){return point(A.x+B.x,A.y+B.y);}
    point operator -(point A,point B){return point(A.x-B.x,A.y-B.y);}
    double getangle(point a){ return atan2(a.y,a.x);}
    double getangle(line a){ return getangle(a.p);}
    point llintersect(line A,line B)
    {
        point C=A.a-B.a;
        double t=det(C,B.p)/det(B.p,A.p);
        return A.a+A.p*t;
    }
    point s[maxn]; line t[maxn],q[maxn]; int head,tail;
    bool cmp(line a,line b){
        double A=getangle(a),B=getangle(b);
        point t=(b.a+b.p)-a.a;
        if(fabs(A-B)<eps) return det(a.p,t)>=0.0;
        return A<B;
    }
    bool onright(line P,line a,line b)
    {
        point o=llintersect(a,b);
        point Q=o-P.a;
        return det(Q,P.p)>0; //如果同一直线上不能相互看到,则>=0
    }
    bool halfplaneintersect(int N)
    {
        s[N+1]=s[1];
        rep(i,1,N) t[i].a=s[i],t[i].p=s[i+1]-s[i];
        sort(t+1,t+N+1,cmp);
        int tot=0;
        rep(i,1,N-1) {
            if(fabs(getangle(t[i])-getangle(t[i+1]))>eps)
              t[++tot]=t[i];
        }
        t[++tot]=t[N]; head=tail=0;
        rep(i,1,tot){
            while(tail>head+1&&onright(t[i],q[tail],q[tail-1])) tail--;
            while(tail>head+1&&onright(t[i],q[head+1],q[head+2])) head++;
            q[++tail]=t[i];
        }
        while(tail>head+1&&onright(t[head+1],q[tail],q[tail-1])) tail--;return tail-head>2;
    }
    void solve(int C,int N)
    {
        for(int i=N;i>=1;i--) scanf("%lf%lf",&s[i].x,&s[i].y);
        printf("Floor #%d
    ",C);
        if(halfplaneintersect(N)) puts("Surveillance is possible.
    ");
        else puts("Surveillance is impossible.
    ");
    }
    int main()
    {
        int N,C=0;
        while(~scanf("%d",&N)&&N) solve(++C,N);
        return 0;
    }
  • 相关阅读:
    哈利波特买书事件
    闹钟类app构想
    梦断代码(7-尾)
    梦断代码(3-6)
    梦断代码(0-2)
    环形二维数组求最大子矩阵
    数组问题
    电梯考察
    四则运算的三张计划表
    团队开发用户需求调研
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10670137.html
Copyright © 2020-2023  润新知