zrq495
www.zrq495.com

凸包 + 枚举。

代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 
 8 using namespace std;
 9 
10 typedef struct node
11 {
12     int x, y;
13 }node;
14 
15 node f[50002];
16 
17 bool cmp(node a,node b)    //叉积排序 如果相等 近的优先
18 {
19     if((a.x-f[0].x)*(b.y-f[0].y) == (b.x-f[0].x)*(a.y-f[0].y))
20     return ((a.x-f[0].x)*(a.x-f[0].x)+(a.y-f[0].y)*(a.y-f[0].y))
21             < ((f[0].x-b.x)*(f[0].x-b.x)+(f[0].y-b.y)*(f[0].y-b.y));
22     return (a.x-f[0].x)*(b.y-f[0].y) > (b.x-f[0].x)*(a.y-f[0].y);
23 }
24 
25 bool left(int i, int j, int k)    //判断是否左转
26 {
27     int x1=f[j].x-f[i].x;
28     int y1=f[j].y-f[i].y;
29     int x2=f[k].x-f[j].x;
30     int y2=f[k].y-f[j].y;
31     if (x1*y2 > x2*y1)     //这种情况为不要直线上多余的点 如果想要应用 >=
32         return true;
33     return false;
34 }
35 
36 int dis(int i, int j)    //求两点距离平方
37 {
38     return (f[i].x-f[j].x)*(f[i].x-f[j].x)
39             +(f[i].y-f[j].y)*(f[i].y-f[j].y);
40 }
41 
42 int main()
43 {
44     int n, i, j, k;
45     int st[50002];   //储存凸包顶点
46     while(scanf("%d", &n)!=EOF)
47     {
48         k=0;
49         for (i=0; i<n; i++)
50         {
51             scanf("%d%d", &f[i].x, &f[i].y);
52             if (f[i].y < f[k].y || (f[i].y==f[k].y && f[i].x <f[k].x))  
53                 k=i;                               
54         }
55         if (k != 0)
56         {
57             swap(f[0].x, f[k].x);
58             swap(f[0].y, f[k].y);
59         }
60         sort(f+1, f+n, cmp);
61         int top=0;
62         st[top++]=0;
63         st[top++]=1;
64         st[top++]=2;
65         for (i=3; i<n; )
66         {
67             if (top < 2 || left(st[top-2], st[top-1], i)) //是左转则入栈加一 (top<2)的情况是对于开始就有直线又不要直线上多余点的情况,
68                 st[top++]=i++;                 //防止越界。如果直线上多余的点也要则可不写,但会有多余的点使得效率低
69             else
70                 top--;
71         }
72         st[top]=st[0];
73         int d=0;
74         for (i=0; i<top; i++)  //枚举求最大距离平方
75         {
76             for (j=i+1; j<top; j++)
77             {
78                 if (d < dis(st[i], st[j]))
79                     d=dis(st[i], st[j]);
80             }
81         }
82         printf("%d\n", d);
83     }
84     return 0;
85 }
posted on 2012-08-16 19:15  zrq495  阅读(194)  评论(0编辑  收藏  举报