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]);
	}
}


转载于:https://www.cnblogs.com/yobobobo/archive/2012/08/16/3826858.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值