您的位置:首页 > 其它

POJ 1228 稳定凸包

2013-02-24 18:54 274 查看
题意:

这里讲的很清楚:

http://www.cnblogs.com/xdruid/archive/2012/06/20/2555536.html

我们一般的凸包模板都是最简的,而稍作变化就能做到“最繁”的~

View Code

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#include <cmath>

#define N 2222

using namespace std;

struct PO
{
int x,y;
}p
;

int n,top,stk
,fg
;

inline bool cmp(const PO &a,const PO &b)
{
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}

inline void read()
{
memset(fg,0,sizeof fg);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d",&p[i].x,&p[i].y);
}

inline int cross(PO &a,PO &b,PO &c)
{
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}

inline int dot(PO &a,PO &b,PO &c)
{
return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);
}

inline void graham()//带共线的graham
{
sort(p+1,p+1+n,cmp);
top=0;
stk[++top]=1; stk[++top]=2;
int tmp;
for(int i=3;i<=n;i++)
{
while(top>=2&&((tmp=cross(p[stk[top-1]],p[stk[top]],p[i]))<0||(tmp==0&&dot(p[stk[top-1]],p[stk[top]],p[i])<=0))) top--;
stk[++top]=i;

}
int tp=top;
for(int i=n-1;i>=1;i--)
{
while(top>=tp+1&&((tmp=cross(p[stk[top-1]],p[stk[top]],p[i]))<0||(tmp==0&&dot(p[stk[top-1]],p[stk[top]],p[i])<=0))) top--;
stk[++top]=i;
}
}

inline bool allinline()//全部共线
{
for(int i=3;i<=n;i++)
if(cross(p[1],p[2],p[i])!=0) return false;
return true;
}

inline bool judge()
{
if(n<6) return false;
if(allinline()) return false;
return true;
}

inline void go()
{
if(!judge()) {puts("NO");return;}
graham();
if(top-1<6) {puts("NO");return;}
stk[top+1]=stk[2];
for(int i=1;i<top;i++)
if(cross(p[stk[i]],p[stk[i+1]],p[stk[i+2]])==0) fg[i+1]=fg[i+2]=1;
fg[1]|=fg[top]; fg[2]|=fg[top+1];
for(int i=1;i<top;i++)
if(!fg[i]) {puts("NO");return;}
puts("YES");
}

int main()
{
int cas; scanf("%d",&cas);
while(cas--) read(),go();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: