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