POJ 1228 Grandpa's Estate

题目原文

    题目大意就是给你一些凸多边形上面的点,让你判断是否所有的边上都至少有三个点,水题,直接上代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define N 1005
#define EPS 1e-6
using namespace std;
struct point
{
    int x,y;
    double len,theta;
    int num;
} g[N];
void qsort(int st,int en)
{
    int i=st,j=en;
    g[0]=g[i];
    while(i<j)
    {
        while(i<j && g[0].theta>=g[j].theta) j--;
        if(i<j) { g[i]=g[j]; i++; }
        while(i<j && g[i].theta>=g[0].theta) i++;
        if(i<j) { g[j]=g[i]; j--; }
    }
    g[i]=g[0];
    if(st<i-1) qsort(st,i-1);
    if(i+1<en) qsort(i+1,en);
}
bool graham(int *n)
{
    int p=1;
    for(int i=2;i<=*n;i++)
      if( (g[p].y>g[i].y) || (g[p].y==g[i].y && g[p].x>g[i].x)) p=i;
    g[0]=g[p]; g[p]=g[1]; g[1]=g[0];
    for(int i=2;i<=*n;i++)
    {
        g[i].len=sqrt((g[i].x-g[1].x)*(g[i].x-g[1].x)+(g[i].y-g[1].y)*(g[i].y-g[1].y));
        g[i].theta=(g[i].x-g[1].x)/g[i].len;
    }
    qsort(2,*n); g[*n+1]=g[1]; (*n)++;
    int p1=1,p2=2,k=p1+2,tot=1;
    while(p1<*n)
    {
        int pp=(g[p1].len>g[p2].len)?p1:p2;
        double chaji=(g[p1].x-g[p2].x)*(g[p2].y-g[k].y)-(g[p2].x-g[k].x)*(g[p1].y-g[p2].y);
        while(fabs(chaji)<=EPS && k<=*n)
        {
            if(g[k].len>g[pp].len) pp=k;
            k++;
            chaji=(g[p1].x-g[p2].x)*(g[p2].y-g[k].y)-(g[p2].x-g[k].x)*(g[p1].y-g[p2].y);
        }
        if(k==p2+1) return false;
        else if(p1==1 && k>*n) return false;
        if(tot==1) { p1=pp; p2=k; k++; tot++; }
        else { p1=k-1; p2=k; k++; }
    }
    return true;
}
int main()
{
    int t,n;
    scanf("%d",&t);
    for(int ca=1;ca<=t;ca++)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&g[i].x,&g[i].y);
        if(n<=5) printf("NO\n");
        else
        {
            bool ans=graham(&n);
            if(ans) printf("YES\n"); else printf("NO\n");
        }
    }
    return 0;
}


你可能感兴趣的:(POJ 1228 Grandpa's Estate)