Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 28659 | Accepted: 8898 |
Description
Input
Output
Sample Input
4 0 0 0 1 1 1 1 0
Sample Output
2
涨知识了、旋转卡(qia)壳
前面写凸包都是从1开始的、这里改为从0开始、方便一点
附暴力程序、或许是因为数据弱了、所以旋转卡壳算法再本题的时间上没有太大优化。
#include<iostream> #include<algorithm> #include<cmath> #include<cstdio> using namespace std; #define N 100010 struct Point { int x,y; Point(){} Point (int x,int y):x(x),y(y){ } Point operator -(Point p){ return Point(x-p.x,y-p.y); } int operator * (Point p){ return x*p.x+y*p.y; } int operator ^ (Point p){ return x*p.y-y*p.x; } bool operator < (const Point &p)const { if(x!=p.x) return x<p.x; return y<p.y; } }; int n; int top; Point p[N],q[N]; void Graham() { int i; sort(p,p+n); top=0; for(i=0;i<n;i++) { while(top>1 && ((q[top-1]-q[top-2])^(p[i]-q[top-2]))<=0) top--; q[top++]=p[i]; } int t=top; for(i=n-1;i>=0;i--) { while(top>t && ((q[top-1]-q[top-2])^(p[i]-q[top-2]))<=0) top--; q[top++]=p[i]; } top-=1; } int dis(Point a,Point b) { return (a-b)*(a-b); } void solve() { int i,j,ans=-1; for(i=0;i<top-1;i++) { for(j=i+1;j<top;j++) { ans=max(ans,dis(q[i],q[j])); } } cout<<ans<<endl; } void Rotate_Caliper() { Point v; int ans=0,cur=1; for(int i=0;i<top;i++) { v=q[i]-q[(i+1)%top]; while((v^(q[(cur+1)%top]-q[cur]))<0) cur=(cur+1)%top; ans=max(ans,max(dis(q[i],q[cur]),dis(q[(i+1)%top],q[(cur+1)%top]))); } cout<<ans<<endl; } int main() { while(scanf("%d",&n)!=EOF) { for(int i=0;i<n;i++) { scanf("%d%d",&p[i].x,&p[i].y); } Graham(); //暴力:solve(); Rotate_Caliper(); } return 0; }