poj 2187 简单凸包

开始以为cxlove出错题目了,给了个大水题得意,简单的枚举嘛。。。。。果断TLE。。。。。

后来还是以为是水题,就想找边界点(左上角,右上角,左下角,右上角之类的点)

但是写着写着,何为左上?当左和上冲突时,选择哪个??!  写着写着发现不行。。。。

边界?——————————》凸包。。。。枚举凸包边上的点吧,不过这次要注意,原来的凸包把中间点删去了,可是这时候要保留

今天从cxlove那学到的总算用上了,虽然花了一个下午来弄一个模版,不过感觉对凸包的理解更深一层了,总算没白费

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<vector>
#define val 50005
#define zero(x) (((x)>0?(x):-(x))<eps)
using namespace std;
typedef struct{int x,y;}point;
int n;
point p[val];
vector<point> s;
template <class T>  
inline bool scan_d(T &ret) {  
   char c; int sgn;  
   if(c=getchar(),c==EOF) return 0; //EOF  
   while(c!='-'&&(c<'0'||c>'9')) c=getchar();  
   sgn=(c=='-')?-1:1;  
   ret=(c=='-')?0:(c-'0');  
   while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');  
   ret*=sgn;  
   return 1;  
}  
int xmult(point p1,point p2,point p0)
{
	return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
int dist(point p1,point p2)
{
	return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
void graham_scan();
bool cmp(const point &p1,const point &p2)
{
	int temp;
	temp=xmult(p[0],p1,p2);
	if(temp>0) return true;
	else if(temp==0&&dist(p1,p[0])<dist(p2,p[0]))
		return true;
	return false;
}
int main()
{
	int i,j,ans,temp;
	while(scanf("%d",&n)!=EOF)
	{
		ans=0;
		for(i=0;i<n;i++)
		{
			scan_d(p[i].x);
			scan_d(p[i].y);
			if(p[i].y<p[0].y) swap(p[i],p[0]);
			else if(p[i].y==p[0].y&&p[i].x<p[0].x) swap(p[i],p[0]);
		}
		if(n==2)
		{
			printf("%d\n",dist(p[0],p[1]));
			continue;
		}
		graham_scan();
		n=s.size();
		for(i=0;i<n;i++)
			for(j=i+1;j<n;j++)
			{
				temp=dist(s[i],s[j]);
				if(temp>ans)  ans=temp;
			}
		printf("%d\n",ans);
	}
	return 0;
}
void graham_scan()
{
	s.clear();
	int i,end;
	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])<0)
				s.pop_back();
			else break;
		}
		s.push_back(p[i]);
	}
}


你可能感兴趣的:(c,struct,Class,ini)