您的位置:首页 > 其它

poj 2187 简单凸包

2012-08-16 23:32 381 查看
开始以为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]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: