现在的位置: 首页 > 综合 > 正文

poj 1228 完整凸包

2013年01月03日 ⁄ 综合 ⁄ 共 1479字 ⁄ 字号 评论关闭

不做不知道,做了才发现凸包的模版错的太多了。。。。。

感谢cxlove的耐心纠错。。。。。。。终于能有个比较好的凸包模版了。。。。两页的WA。。。。。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<stack>
#include<math.h>
#define zero(x) (((x)>0?(x):-(x))<eps)
#define eps 1e-8
#define val 1005
using namespace std;
typedef struct node{double x,y;}point;
int pos,n;
point p[val];
vector<point> s;
double dist(point p1,point p2)
{
	return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double xmult(point p1,point p2,point p0)
{
	return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
bool cmp(const node &p1,const node &p2)
{
	double temp;
	temp=xmult(p[0],p1,p2);
	if(temp>0) return true;
	if(zero(temp)&&dist(p1,p[0])<dist(p2,p[0]))//距离小的靠前,通过远的弹出近的
		return true;
	return false;
}
void graham();
int main()
{
	int i,num,cnt,cas;
	bool flag;
	for(scanf("%d",&cas);cas;cas--)
	{
		scanf("%d",&n);
		s.clear();
		for(i=0;i<n;i++)
		{
			scanf("%lf%lf",&p[i].x,&p[i].y);
			if(p[i].y<p[0].y) swap(p[i],p[0]);
			else if(zero(p[i].y-p[0].y)&&p[i].x<p[0].x)
				swap(p[i],p[0]);
		}
		graham();
		s.push_back(s[0]);
		flag=false;
		if(n<=5) 
		{
			printf("NO\n");
			continue;
		}
		for(i=0;i<s.size()-1;i++)
		{
			cnt=0;
			for(int j=0;j<n;j++)
				if(zero(xmult(s[i],s[i+1],p[j])))   cnt++;
			if(cnt<3)
			{
				flag=true;
				break;
			}
		}
		for(i=2;i<n;i++)
			if(!zero(xmult(p[i],p[i-1],p[i-2]))) break;
		if(i>=n) flag=true;
		if(flag) printf("NO\n");
		else printf("YES\n");
	}
	return 0;
}
void graham()
{
	int i,end;
	pos=0;
	sort(p+1,p+n,cmp);
	for(i=0;i<3;i++) s.push_back(p[i]);
	for(i=3;i<n;i++)
	{
		while(1)
		{
			end=s.size()-1;
			if(s.size()>=2&&xmult(s[end-1],s[end],p[i])<eps)//共线的就不要放了
				s.pop_back();
			else break;
		}
		s.push_back(p[i]);
	}
	return ;
}

抱歉!评论已关闭.