POJ - 2187 Beauty Contest(最远点对)
http://poj.org/problem?id=2187
题意
给n个坐标,求最远点对的距离平方值。
分析
模板题,旋转卡壳求求两点间距离平方的最大值。
#include<iostream> #include<cmath> #include<cstring> #include<queue> #include<vector> #include<cstdio> #include<algorithm> #include<map> #include<set> #define rep(i,e) for(int i=0;i<(e);i++) #define rep1(i,e) for(int i=1;i<=(e);i++) #define repx(i,x,e) for(int i=(x);i<=(e);i++) #define X first #define Y second #define PB push_back #define MP make_pair #define mset(var,val) memset(var,val,sizeof(var)) #define scd(a) scanf("%d",&a) #define scdd(a,b) scanf("%d%d",&a,&b) #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c) #define pd(a) printf("%d\n",a) #define scl(a) scanf("%lld",&a) #define scll(a,b) scanf("%lld%lld",&a,&b) #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c) #define IOS ios::sync_with_stdio(false);cin.tie(0) #define lc idx<<1 #define rc idx<<1|1 #define rson mid+1,r,rc #define lson l,mid,lc using namespace std; typedef long long ll; template <class T> void test(T a) { cout<<a<<endl; } template <class T,class T2> void test(T a,T2 b) { cout<<a<<" "<<b<<endl; } template <class T,class T2,class T3> void test(T a,T2 b,T3 c) { cout<<a<<" "<<b<<" "<<c<<endl; } const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3fll; const ll mod = 1e9+7; int T; void testcase() { printf("Case %d: ",++T); } const int MAXN = 50010; const int MAXM = 30; const double PI = acos(-1.0); const double eps = 1e-7; struct Point{ int x,y; Point(int _x=0,int _y=0){ x=_x,y=_y; } Point operator -(const Point &b)const{ return Point(x-b.x,y-b.y); } int operator ^(const Point &b)const{ return x*b.y-y*b.x; } int operator *(const Point &b)const{ return x*b.x+y*b.y; } void input(){ scanf("%d%d",&x,&y); } }; int dis2(Point a,Point b){ return (a-b)*(a-b); } Point List[MAXN]; int Stack[MAXN],top; bool _cmp(Point p1,Point p2){ int tmp=(p1-List[0])^(p2-List[0]); if(tmp>0) return true; else if(tmp==0&&dis2(p1,List[0])<=dis2(p2,List[0])) return true; else return false; } void Graham(int n){ Point p0; int k=0; p0=List[0]; for(int i=1;i<n;i++){ if(p0.y>List[i].y||(p0.y==List[i].y&&p0.x>List[i].x)){ p0=List[i]; k=i; } } swap(List[k],List[0]); sort(List+1,List+n,_cmp); if(n==1){ top=1; Stack[0]=0; return; } if(n==2){ top=2; Stack[0]=0; Stack[1]=1; return; } Stack[0]=0; Stack[1]=1; top=2; for(int i=2;i<n;i++){ while(top>1&&((List[Stack[top-1]]-List[Stack[top-2]])^(List[i]-List[Stack[top-2]]))<=0) top--; Stack[top++]=i; } return; } int rotating_calipers(Point p[],int n){ int ans=0; Point v; int cur=1; for(int i=0;i<n;i++){ v=p[i]-p[(i+1)%n]; while((v^(p[(cur+1)%n]-p[cur]))<0) cur=(cur+1)%n; ans=max(ans,max(dis2(p[i],p[cur]),dis2(p[(i+1)%n],p[(cur+1)%n]))); } return ans; } Point p[MAXN]; int main() { #ifdef LOCAL freopen("data.in","r",stdin); #endif // LOCAL int n; while(~scanf("%d",&n)){ for(int i=0;i<n;i++) List[i].input(); Graham(n); for(int i=0;i<top;i++) p[i]=List[Stack[i]]; printf("%d\n",rotating_calipers(p,top)); } return 0; }