zoukankan      html  css  js  c++  java
  • POJ

    题目链接:https://vjudge.net/problem/POJ-1228

    题意:给你一堆点,这堆点本来就是某个凸包上的部分点,问你这堆点是否能确定唯一的凸包,这种凸包叫做稳定凸包。

    稳定凸包的含义:当凸包上存在一条边上的点只有端点两个点的时候,这个凸包不是稳定的,因为它可以在这条边外再引入一个点,构成一个新的凸包。

    但一旦一条边上存在三个点,那么不可能再找到一个点使它扩展成一个新的凸包,否则构成的新多边形将是凹的。

    思路:先根据给定的点求出凸包,在求凸包时,不需要把斜率一样位置近的点去掉。然后再看求出凸包的点上是否每条线上至少有三个点就可以了。

    #include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<map>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const double PI = atan(1.0)*4.;
    const int maxn=200005;
    struct point
    {
        double x,y;
        point friend operator -(point A,point B)
        {
            return {A.x-B.x,A.y-B.y};
        }
    };
    struct line
    {
        point x,y;
    };
    point p[maxn];//输入点集
    point q[maxn];//凸包点集
    double dis(point A,point B)//两点的距离
    {
        return sqrt( (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y) );
    }
    double chaj(point A,point B)//差积
    {
        return A.x*B.y-A.y*B.x;
    }
    bool cmp(point A,point B)//以p[0]为起点,按差积逆时针排序
    {
        double s=chaj(A-p[1],B-p[1]);
        if(s>0)
            return true;
        if(s==0)
            return dis(A,p[1])<dis(B,p[1]);
        return false;
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            int N;
            cin>>N;
            for(int i=1; i<=N; i++)
                cin>>p[i].x>>p[i].y;
            if(N<6)
            {
                cout<<"NO"<<endl;
                continue;
            }
            //找到最小的点
            int K=1;
            for(int i=2; i<=N; i++)
            {
                if(p[i].y<p[K].y||(p[i].y==p[K].y&&p[i].x<p[K].x))
                    K=i;
            }
            swap(p[1],p[K]);
    
            sort(p+2,p+1+N,cmp);
    
            q[1]=p[1];
            q[2]=p[2];
            int len=2;//凸包点的个数
            for(int i=3; i<=N; i++)
            {
                while(len>=2&&chaj(q[len]-q[len-1],p[i]-q[len-1])<0)
                    len--;
                q[++len]=p[i];
            }
            q[++len]=q[1];
            int flag=1;
            for(int i=3;i<len;i++)
            {
                if(chaj(q[i-1]-q[i-2],q[i]-q[i-1])!=0&&chaj(q[i]-q[i-1],q[i+1]-q[i])!=0)
                    flag=0;
            }
            if(flag)
                cout<<"YES"<<endl;
            else
                cout<<"NO"<<endl;
        }
    }
  • 相关阅读:
    技术的那些事儿_2_产品与工艺
    for与foreach再探讨
    技术的那些事儿_3_西方技术管理的精髓
    搭建免费的.Net开发环境
    CDN
    servu 系统服务看门狗,自动脱机补丁,自动启动
    .NET Remoting程序开发入门篇
    网管必知远程终端3389端口合理修改秘藉
    反射方法调用时的一个错误:参数计数不匹配( parameter count mismatch )
    VPS性能测试第一步:CPU测试
  • 原文地址:https://www.cnblogs.com/zcb123456789/p/13809405.html
Copyright © 2011-2022 走看看