Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 33122 | Accepted: 10282 |
Description
Input
Output
Sample Input
4 0 0 0 1 1 1 1 0
Sample Output
2
Hint
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N = 50005; struct Point{ int x,y; }p[N],Stack[N]; int n; int mult(Point a,Point b,Point c){ return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y); } int dis(Point a,Point b){ return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } int cmp(Point a,Point b){ if(mult(a,b,p[0])>0) return 1; if(mult(a,b,p[0])==0&&dis(b,p[0])>dis(a,p[0])) return 1; return 0; } int Graham(){ sort(p+1,p+n,cmp); int top = 2; Stack[0]=p[0]; Stack[1]=p[1]; Stack[2]=p[2]; for(int i=3;i<n;i++){ while(top>=1&&mult(p[i],Stack[top],Stack[top-1])>=0){ top--; } Stack[++top]=p[i]; } return top; } int main() { while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i++){ scanf("%d%d",&p[i].x,&p[i].y); } int k = 0; for(int i=1;i<n;i++){ if(p[k].y>p[i].y||(p[k].y==p[i].y)&&(p[k].x>p[i].x)){ k=i; } } swap(p[0],p[k]); int top = Graham(); int ans =0; for(int i=0;i<=top;i++){ for(int j=i+1;j<=top;j++){ if(ans<dis(Stack[i],Stack[j])){ ans = dis(Stack[i],Stack[j]); } } } printf("%d\n",ans); } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int N = 50005; struct Point{ int x,y; }p[N],Stack[N]; int n; int mult(Point a,Point b,Point c){ return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y); } int dis(Point a,Point b){ return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } int cmp(Point a,Point b){ if(mult(a,b,p[0])>0) return 1; if(mult(a,b,p[0])==0&&dis(b,p[0])>dis(a,p[0])) return 1; return 0; } int Graham(){ sort(p+1,p+n,cmp); int top = 2; Stack[0]=p[0]; Stack[1]=p[1]; Stack[2]=p[2]; for(int i=3;i<n;i++){ while(top>=1&&mult(p[i],Stack[top],Stack[top-1])>=0){ top--; } Stack[++top]=p[i]; } return top; } int rotating_calipers(int top)//旋转卡壳 { int q=1,ans=0,p; Stack[++top]=Stack[0]; ///将最后一个点和第一点的边也要算进去,于是多加一个点表示第一个点 for(p=0; p<top; p++) { ///找到以Stack[p] 和 Stack[p+1]这两个点为底边的最大三角形 (叉积之积为三角形有向面积)(图1) while(mult(Stack[p],Stack[p+1],Stack[q+1])>mult(Stack[p],Stack[p+1],Stack[q+1])) q=(q+1)%top; ///在底边的两个点中选择与顶点距离大的 ans=max(ans,max(dis(Stack[p],Stack[q]),dis(Stack[p+1],Stack[q]))); } return ans; } int main() { while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i++){ scanf("%d%d",&p[i].x,&p[i].y); } int k = 0; for(int i=1;i<n;i++){ if(p[k].y>p[i].y||(p[k].y==p[i].y)&&(p[k].x>p[i].x)){ k=i; } } swap(p[0],p[k]); //printf("%d %d\n",p[0].x,p[0].y); int top = Graham(); int ans =rotating_calipers(top); printf("%d\n",ans); } return 0; }