poj 2187 Beauty Contest (凸包)

题目:http://poj.org/problem?id=2187

题意:给定平面上的一些散点集,求最远两点距离的平方值。

基于水平序的Andrew算法(Graham算法的变种)

1、按照x从小到大排序(如果x相同就按照y从小到大排序),删除重复点后得到序列p1,p2,。。。。

2、把p1和p2放到凸包中。从p3开始,当新点在凸包的前进方向的左边时继续,否则依次删除最近加入凸包的点,直到新点在左边。

3、依次枚举凸包的的任意两点,求出最大距离的平方

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 const double eps=1e-6;
 7 typedef struct node
 8 {
 9     int x,y;
10 }point;
11 int n;
12 point pt[50010];
13 point res[50010];
14 bool cmp(point a,point b)
15 {
16     if(a.x==b.x)
17     return a.y<b.y;
18     else
19     return a.x<b.x;
20 }
21 int dcml(double x)
22 {
23     if(fabs(x)<eps)
24     return 0;
25     if(x<0)
26     return -1;
27     else
28     return 1;
29 }
30 double dot(int x1,int y1,int x2,int y2)
31 {
32     return x1*y2-x2*y1;
33 }
34 int cross(point a,point b,point c)
35 {
36     return dcml(dot(a.x-c.x,a.y-c.y,b.x-c.x,b.y-c.y));
37 }
38 int dist(point a,point b)
39 {
40     return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
41 }
42 int main()
43 {
44     scanf("%d",&n);
45     int i;
46     for(i=0;i<n;i++)
47     {
48         scanf("%d%d",&pt[i].x,&pt[i].y);
49     }
50     sort(pt,pt+n,cmp);
51     int m;
52     m=0;
53     for(i=0;i<n;i++)
54     {
55         while(m>1&&cross(res[m-1],pt[i],res[m-2])<=0)
56         m--;
57         res[m++]=pt[i];
58     }
59     int k=m;
60     for(i=n-2;i>=0;i--)
61     {
62         while(m>k&&cross(res[m-1],pt[i],res[m-2])<=0)
63         m--;
64         res[m++]=pt[i];
65     }
66     if(n>1)
67     m--;
68     int dis=0;
69     int j;
70     for(i=0;i<m;i++)
71     {
72         for(j=i+1;j<m;j++)
73         {
74             int h=dist(res[i],res[j]);
75             if(dis<h)
76             dis=h;
77         }
78     }
79     printf("%d\n",dis);
80     return 0;
81 }

 

posted @ 2013-03-08 17:44  琳&leen  阅读(153)  评论(0编辑  收藏  举报