poj 2187 Beauty Contest

求平面最远点对。

朴素的O(n^2)算法显然超时。这里用到了一种旋转卡壳算法,逆时针开始找,找到第一对对踵点(被一对卡壳正好卡住的对应点),那么以后的点也必然是逆时针排列的。找对踵点可以用一条边找另一点使得该三角形面积最大,之后比较边端点与该点距离即可。

View Code
 1 /*
 2 Coder:Zhaofa Fang
 3 Lang:C++
 4 */
 5 #include <cstdio>
 6 #include <cstdlib>
 7 #include <iostream>
 8 #include <cmath>
 9 #include <cstring>
10 #include <algorithm>
11 #include <string>
12 #include <vector>
13 #include <queue>
14 #include <stack>
15 #include <map>
16 #include <set>
17 #define pb push_back
18 using namespace std;
19 
20 //==========================================
21 const double PI=acos(-1);
22 
23 struct Point
24 {
25     double x,y;
26 }point[50005],res[50005];
27 
28 double det(double x1,double y1,double x2,double y2)
29 {
30     return x1*y2-x2*y1;
31 }
32 double xmult(Point o,Point a ,Point b)
33 {
34     return det(a.x-o.x,a.y-o.y,b.x-o.x,b.y-o.y);
35 }
36 double dis(Point a,Point b)
37 {
38     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
39 }
40 int dis1(Point a,Point b)
41 {
42     return (int)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
43 }
44 bool cmp(const Point &x,const Point &y)
45 {
46     if(xmult(point[0],x,y)==0)
47         return dis(point[0],x)<dis(point[0],y);
48     return xmult(point[0],x,y)>0;
49 }
50 int Graham(int n)
51 {
52     Point tmp;
53     int k=0,top=2;
54     for(int i=1;i<n;i++)
55     {
56         if(point[i].y<point[k].y || point[i].y==point[k].y && point[i].x<point[k].x)
57         k=i;
58     }
59     tmp=point[0],point[0]=point[k],point[k]=tmp;
60     sort(point+1,point+n,cmp);
61     res[0]=point[0],res[1]=point[1],res[2]=point[2];
62     for(int i=3;i<n;i++)
63     {
64         while(top && xmult(res[top-1],res[top],point[i])<=0)top--;
65         res[++top]=point[i];
66     }
67     return top+1;
68 }
69 int rotating(int n)
70 {
71     int q=1;
72     int ans=0;
73     res[n]=res[0];
74     for(int p=0;p<n;p++)
75     {
76         while(fabs(xmult(res[q+1],res[p+1],res[p])) > fabs(xmult(res[q],res[p+1],res[p])))
77         q=(q+1)%n;
78         ans=max(ans,max(dis1(res[p],res[q]),dis1(res[p+1],res[q])));
79     }
80     return ans;
81 }
82 int main()
83 {
84     int n;
85     while(~scanf("%d",&n))
86     {
87         for(int i=0;i<n;i++)
88         {
89             scanf("%lf%lf",&point[i].x,&point[i].y);
90         }
91         int mount=Graham(n);
92         printf("%d\n",rotating(mount));
93     }
94     return 0;
95 }

 

 

posted @ 2012-08-06 22:39  發_  阅读(118)  评论(0编辑  收藏  举报