• Kingdom of Kittens


    这....好多坑啊...照着学长的代码抄的(捂脸)
    1、求凸包的时候 一个点返回的凸包时空的。我人傻了。
    2、我一开始是求非严格凸包的点数与n进行比较,及其傻逼!n个点共线的时候会求出来诡异的结果。
    所以还是要求凸包然后每个点进行判断啊。
    思路很神妙啊!比我的不知道神妙到哪里去了。。
    首先先看凸包的边上是否严格存在点嘛,
    然后枚举两条边,
    这两条边只可能是相邻的,或者中间间隔一条边并且这条边上没有点。
    然后考虑check,一个显然的性质是凸包边数比较多的时候就GG了,可以盲猜一下是6
    说真的我一开始虽然可能注意到了这条性质但是完全没有想到可以使问题简化这么多。
    然后我们看看另一边有几个点,以及能否连出来一个三角形,,这边好zz啊,
    比方说y+1到x中间有两个点的话,我们要判这两个点的斜率和x,x+1 以及 y,y+1能不能连成三角形
    唔.没了,
    请自觉忽略#define

    #include <bits/stdc++.h>
    #define yxn inline
    #define INF 19970404
    using namespace std;
    typedef long long db;
    yxn int sign(db k){
        if (k>0) return 1; else if (k<0) return -1; return 0;
    }
    yxn int cmp(db k1,db k2){return sign(k1-k2);}
    yxn int inmid(db k1,db k2,db k3){return sign(k1-k3)*sign(k2-k3)<=0;}
    struct point{
        db x,y;
        point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};}
        point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};}
        point operator * (db k1) const{return (point){x*k1,y*k1};}
        bool operator < (const point k1) const{
            int a=cmp(x,k1.x);
            if (a==-1) return 1; else if (a==1) return 0; else return cmp(y,k1.y)==-1;
        }
    };
    yxn int inmid(point k1,point k2,point k3){return inmid(k1.x,k2.x,k3.x)&&inmid(k1.y,k2.y,k3.y);}
    yxn db cross(point k1,point k2){ return k1.x*k2.y-k1.y*k2.x;}
    yxn db dot(point k1,point k2){ return k1.x*k2.x+k1.y*k2.y;}
    yxn int onS(point k1,point k2,point q){return inmid(k1,k2,q)&&sign(cross(k1-q,k2-k1))==0;}
    yxn vector<point> ConvexHull(vector<point>&A,int flag=1){ // flag=0 不严格 flag=1 严格
        int n=A.size(); vector<point>ans(n*2);
        sort(A.begin(),A.end()); int now=-1;
        for (int i=0;i<A.size();i++){
            while (now>0&&sign(cross(ans[now]-ans[now-1],A[i]-ans[now-1]))<flag) now--;
            ans[++now]=A[i];
        } int pre=now;
        for (int i=n-2;i>=0;i--){
            while (now>pre&&sign(cross(ans[now]-ans[now-1],A[i]-ans[now-1]))<flag) now--;
            ans[++now]=A[i];
        } ans.resize(now); return ans;
    }
    int n,vis[100005];
    point p[100005];
    vector<point> v;
    yxn bool check(int x,int y){
        int m = v.size();
        db p1 = cross(v[(x+1)%m]-v[x],v[(y+1)%m]-v[y]);
        if(p1==0)return false;
        if(p1<0)swap(x,y);
        if((x+1)%m!=y&&(x+2)%m!=y)return false;
        if((x+2)%m==y&&vis[(x+1)%m])return false;
        int cnt=0;
        for(int i=(y+1)%m;i!=x;i=(i+1)%m){
            cnt++;
        }
        if(cnt>=4)return false;
        else if(cnt==3){
            if(vis[(y+1)%m]||vis[(y+3)%m])return false;
            if(cross(v[(y+1)%m]-v[y],v[(y+3)%m]-v[(y+2)%m])>0&&cross(v[(y+3)%m]-v[(y+2)%m],v[(x+1)%m]-v[x])>0)return true;
            return false;
        }else if(cnt==2){
            if(vis[(y+1)%m]&&vis[(y+2)%m])return false;
            if(vis[(y+1)%m]&&cross(v[(y+2)%m]-v[(y+1)%m],v[(x+1)%m]-v[x])<=0)return false;
            if(vis[(y+2)%m]&&cross(v[(y+1)%m]-v[y],v[(y+3)%m]-v[(y+2)%m])<=0)return false;
            return true;
        }
        return true;
    }
    yxn bool check(){
        for(int i=0;i<n;i++){
            bool f=0;
            for(int j=0;j<v.size();j++){
                if(onS(v[j],v[(j+1)%v.size()],p[i]))f=1;
            }
            if(!f)return false;
        }
        return true;
    }
    int main(){
        while (scanf("%d",&n)&&n){
            v.clear();
            for(int i=0;i<n;i++)scanf("%lld%lld",&p[i].x,&p[i].y),v.push_back(p[i]);
            v=ConvexHull(v,1);
            if(v.size()>6)printf("NO
    ");
            else if(v.size()<=2)printf("YES
    ");
            else if(!check())printf("NO
    ");
            else{
                int m = v.size();
                for(int i=0;i<m;i++)vis[i]=0;
                for(int i=0;i<m;i++){
                    for(int j=0;j<n;j++){
                        if(cross(v[(i+1)%m]-v[i],p[j]-v[i])==0&&dot(p[j]-v[i],p[j]-v[(i+1)%m])<0) {
                            vis[i] = 1;
                            break;
                        }
                    }
                }
                bool f=0;
                for(int i=0;i<v.size()&&!f;i++){
                    for(int j=i+1;j<v.size()&&!f;j++){
                        f|=check(i,j);
                    }
                }
                if(f)printf("YES
    ");
                else printf("NO
    ");
            }
        }
    }
    
  • 相关阅读:
    linux下如何查看cpu信息
    Linux更换HBA卡后重新扫盘指令
    oracle 11gR2 RAC存储迁移
    Data Migration from Various Storage Types Using EMC VPLEX and EMC RecoverPoint Technologies
    【11grac】Oracle RAC 更换存储实验
    Oracle RAC 11GR2更换主机不换存储--ASM磁盘组异机挂载 推荐 原创
    ELK(Elasticsearch + Logstash + Kibana) 日志分析平台
    Ogg For Bigdata 同步Oracle数据到KAFKA(包括初始化历史数据)
    stm32cubemx+clion环境搭建
    stdarg宏与实现stm32printf串口打印
  • 原文地址:https://www.cnblogs.com/MXang/p/11621910.html
Copyright © 2020-2023  润新知