poj 2187 N个点中输出2点的最大距离的平方

旋转卡壳

Sample Input

4
0 0
0 1
1 1
1 0
Sample Output

2

 

  1 # include <iostream>
  2 # include <cstdio>
  3 # include <cstring>
  4 # include <algorithm>
  5 # include <string>
  6 # include <cmath>
  7 # include <queue>
  8 # define LL long long
  9 using namespace std ;
 10 
 11 struct Point
 12 {
 13     int x,y;
 14     Point(int _x = 0,int _y = 0)
 15     {
 16         x = _x; y = _y;
 17     }
 18     Point operator -(const Point &b)const
 19     {
 20         return Point(x - b.x, y - b.y);
 21     }
 22     int operator ^(const Point &b)const
 23     {
 24         return x*b.y - y*b.x;
 25     }
 26     int operator *(const Point &b)const
 27     {
 28         return x*b.x + y*b.y;
 29     }
 30     void input()
 31     {
 32         scanf("%d%d",&x,&y);
 33     }
 34 };
 35 //距离的平方
 36 int dist2(Point a,Point b)
 37 {
 38     return (a-b)*(a-b);
 39 }
 40 //******二维凸包,int***********
 41 const int MAXN = 50010;
 42 Point list[MAXN];
 43 int Stack[MAXN],top;
 44 bool _cmp(Point p1,Point p2)
 45 {
 46     int tmp = (p1-list[0])^(p2-list[0]);
 47     if(tmp > 0)return true;
 48     else if(tmp == 0 && dist2(p1,list[0]) <= dist2(p2,list[0]))
 49     return true;
 50     else return false;
 51 }
 52 void Graham(int n)
 53 {
 54     Point p0;
 55     int k = 0;
 56     p0 = list[0];
 57     for(int i = 1;i < n;i++)
 58         if(p0.y > list[i].y || (p0.y == list[i].y && p0.x > list[i].x))
 59         {
 60             p0 = list[i];
 61             k = i;
 62         }
 63     swap(list[k],list[0]);
 64     sort(list+1,list+n,_cmp);
 65     if(n == 1)
 66     {
 67         top = 1;
 68         Stack[0] = 0;
 69         return;
 70     }
 71     if(n == 2)
 72     {
 73         top = 2;
 74         Stack[0] = 0; Stack[1] = 1;
 75         return;
 76     }
 77     Stack[0] = 0; Stack[1] = 1;
 78     top = 2;
 79     for(int i = 2;i < n;i++)
 80     {
 81         while(top > 1 &&
 82         ((list[Stack[top-1]]-list[Stack[top-2]])^(list[i]-list[Stack[top-2]])) <= 0)
 83         top--;
 84         Stack[top++] = i;
 85     }
 86 }
 87 //旋转卡壳,求两点间距离平方的最大值
 88 int rotating_calipers(Point p[],int n)
 89 {
 90     int ans = 0;
 91     Point v;
 92     int cur = 1;
 93     for(int i = 0;i < n;i++)
 94     {
 95         v = p[i]-p[(i+1)%n];
 96         while((v^(p[(cur+1)%n]-p[cur])) < 0)
 97            cur = (cur+1)%n;
 98         ans = max(ans,max(dist2(p[i],p[cur]),dist2(p[(i+1)%n],p[(cur+1)%n])));
 99     }
100     return ans;
101 }
102 Point p[MAXN];
103 int main()
104 {
105     //freopen("in.txt","r",stdin) ;
106     int n;
107     while(scanf("%d",&n) == 1)
108     {
109         for(int i = 0;i < n;i++)
110             list[i].input();
111         Graham(n);
112         for(int i = 0;i < top;i++)p[i] = list[Stack[i]];
113         printf("%d\n",rotating_calipers(p,top));
114     }
115     return 0;
116 }
View Code

 

posted @ 2015-10-11 19:39  __Meng  阅读(185)  评论(0编辑  收藏  举报