• [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;
    }
    
  • 相关阅读:
    HDU 3681 Prison Break(状态压缩dp + BFS)
    POJ 2711 Regular Words(DP + 高精度)
    ZOJ 2745 01-K Code(DP)(转)
    DAG模型——硬币问题
    HDU 1619 Unidirectional TSP(单向TSP + 路径打印)
    DAG模型——嵌套矩阵
    HDU 4294 A Famous Equation(DP)
    HDU 3920 Clear All of Them I(DP + 状态压缩 + 贪心)
    POJ 3254 Corn Fields(DP + 状态压缩)
    HDU 2089 不要62(数位DP)
  • 原文地址:https://www.cnblogs.com/mrha/p/8168625.html
Copyright © 2020-2023  润新知