zoukankan      html  css  js  c++  java
  • [poj] 1228 Grandpa's Estate || 稳定凸包

    原题

    判断给出点形成的凸包是否稳定(点保证在凸包上)
    稳定:无法形成一个新的凸包仍使这些点在凸包上(即每条边上的点至少有3个)


    先求出凸包,然后判断每条边上的点是否大于2个

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 1010
    using namespace std;
    int t,n,m,per[N];
    struct point
    {
        int x,y;
        point() {}
        point(int _x,int _y) : x(_x),y(_y) {}
        point operator - (const point &b) const
    	{
    	    return point(b.x-x,b.y-y);
    	}
        int operator * (const point &b) const
    	{
    	    return x*b.y-b.x*y;
    	}
        bool operator < (const point &b) const
    	{
    	    if (x==b.x) return y<b.y;
    	    return x<b.x;
    	}
        int norm()
    	{
    	    return x*x+y*y;
    	}
    }p[N],q[N];
    
    int dot(point a,point b)
    {
        return a.x*b.x+a.y*b.y;
    }
    
    struct Line
    {
        point a,b;
        int cnt;
        void init(point x,point y)
    	{
    	    a=x;
    	    b=y;
    	    cnt=0;
    	}
        int online(point k)
    	{
    	    int d=(a-k)*(b-k);
    	    if (d!=0) return 0;
    	    if (dot(a-k,b-k)>0) return 0;
    	    return 1;
    	}
    }line[N];
    
    bool cmp(int i,int j)
    {
        int d=(p[i]-p[1])*(p[j]-p[1]);
        if (d!=0) return d>0;
        return (p[i]-p[1]).norm()<(p[j]-p[1]).norm();
    }
    
    void Graham()
    {
        int id=1;
        for (int i=2;i<=n;i++)
    	if (p[i]<p[id]) id=i;
        if (id!=1) swap(p[1],p[id]);
        for (int i=1;i<=n;i++) per[i]=i;
        sort(per+2,per+n+1,cmp);
        q[++m]=p[1];
        for (int i=2,j;i<=n;i++)
        {
    	j=per[i];
    	while (m>=2 && (p[j]-q[m-1])*(q[m]-q[m-1])>=0)
    	    m--;
    	q[++m]=p[j];
        }
    }
    
    bool solve()
    {
        q[m+1]=q[1];
        for (int i=1;i<=m;i++)
    	line[i].init(q[i],q[i+1]);
        for (int i=1;i<=n;i++)
    	for (int j=1;j<=m;j++)
    	    line[j].cnt+=line[j].online(p[i]);
        for (int i=1;i<=m;i++)
    	if (line[i].cnt<=2) return 1;
        return 0;
    }
    
    int main()
    {
        scanf("%d",&t);
        while (t--)
        {
    	scanf("%d",&n);
    	m=0;
    	for (int i=1;i<=n;i++)
    	    scanf("%d%d",&p[i].x,&p[i].y);
    	Graham();
    	if (m<=2 || solve())
    	    puts("NO");
    	else puts("YES");
        }
        return 0;
    }
    
  • 相关阅读:
    Linux之文件处理命令
    Linux基础命令
    rip实验
    Linux基础之磁盘分区
    mysql安装
    centos Apache、php、mysql默认安装路径
    You probably tried to upload too large file. Please refer to documentation for ways to workaround this limit.
    Wrong permissions on configuration file, should not be world writable!
    机器会学习么 学习总结
    实验 5 Spark SQL 编程初级实践
  • 原文地址:https://www.cnblogs.com/mrha/p/8168625.html
Copyright © 2011-2022 走看看