POJ 3348
旋 转卡壳水题。
直接使用旋转卡壳求距离。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN=50100;
struct point {
int x,y;
}p[MAXN];
int n;
int st[MAXN],ans[MAXN];
int stop,cnt;
bool cmp(point A,point B){
if(A.y<B.y) return true;
else if(A.y==B.y){
if(A.x<B.x) return true;
}
return false;
}
int dist(point a,point b){
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
bool multi(point a,point b,point c){
point p,q;
p.x=a.x-c.x; p.y=a.y-c.y;
q.x=b.x-c.x; q.y=b.y-c.y;
return (p.x*q.y-q.x*p.y)>=0;
}
int TriangleArea(point a,point b,point c){
point p,q;
p.x=a.x-c.x; p.y=a.y-c.y;
q.x=b.x-c.x; q.y=b.y-c.y;
return abs(p.x*q.y-q.x*p.y);
}
void slove(){
stop=cnt=0;
st[stop++]=0; st[stop++]=1;
for(int i=2;i<n;i++){
while(stop>1&&multi(p[i],p[st[stop-1]],p[st[stop-2]])) stop--;
st[stop++]=i;
}
for(int i=0;i<stop;i++)
ans[cnt++]=st[i];
stop=0; st[stop++]=n-1; st[stop++]=n-2;
for(int i=n-3;i>=0;i--){
while(stop>1&&multi(p[i],p[st[stop-1]],p[st[stop-2]])) stop--;
st[stop++]=i;
}
for(int i=1;i<stop;i++)
ans[cnt++]=st[i];
}
int for_dist(){
int distant=0;
int q=1;
for(int i=0;i<cnt-1;i++){
while(TriangleArea(p[ans[i]],p[ans[i+1]],p[ans[q+1]])>
TriangleArea(p[ans[i]],p[ans[i+1]],p[ans[q]]))
q=(q+1)%cnt;
distant=max(distant,max(max(dist(p[ans[i]],p[ans[q]]),dist(p[ans[i+1]],p[ans[q+1]])),dist(p[ans[i+1]],p[ans[q]])));
}
return distant;
}
int main(){
while(scanf("%d",&n)!=EOF){
for(int i=0;i<n;i++){
scanf("%d%d",&p[i].x,&p[i].y);
}
sort(p,p+n,cmp);
slove();
printf("%d\n",for_dist());
}
return 0;
}

浙公网安备 33010602011771号