Poj--2187(凸包,枚举顶点)
2014-12-09 22:14:45
思路:由于点很多,可以证明最大距离点对的两个点肯定都在凸包上,所以先求一个凸包,然后枚举凸包顶点即可。
1 /************************************************************************* 2 > File Name: 2187.cpp 3 > Author: Natureal 4 > Mail: 564374850@qq.com 5 > Created Time: Tue 09 Dec 2014 09:43:14 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 50010; 27 28 int N,ans,cnt; 29 struct node{ 30 int x,y; 31 }t[maxn]; 32 33 int cross(node st,node a,node b){ 34 int x1 = a.x - st.x; 35 int y1 = a.y - st.y; 36 int x2 = b.x - st.x; 37 int y2 = b.y - st.y; 38 return x1 * y2 - x2 * y1; 39 } 40 41 bool cmpx(node a,node b){ 42 if(a.x == b.x) 43 return a.y < b.y; 44 return a.x < b.x; 45 } 46 47 bool cmp(node a,node b){ 48 int k = cross(t[1],a,b); 49 if(k == 0){ 50 return cmpx(a,b); 51 } 52 return k > 0; 53 } 54 55 void Graham(){ 56 cnt = 2; 57 for(int i = 3; i <= N; ++i){ 58 while(cnt >= 2 && cross(t[cnt - 1],t[cnt],t[i]) <= 0){ 59 --cnt; 60 } 61 t[++cnt] = t[i]; 62 } 63 } 64 65 int Solve(int l,int r){ 66 int res = 0; 67 for(int i = 1; i <= cnt; ++i){ 68 for(int j = 1; j <= cnt; ++j){ 69 if(i == j) continue; 70 res = max(res,(t[i].x - t[j].x) * (t[i].x - t[j].x) + (t[i].y - t[j].y) * (t[i].y - t[j].y)); 71 } 72 } 73 return res; 74 } 75 76 int main(){ 77 int k = -1; 78 scanf("%d",&N); 79 for(int i = 1; i <= N; ++i){ 80 scanf("%d%d",&t[i].x,&t[i].y); 81 if(k == -1 || cmpx(t[i],t[k])){ 82 k = i; 83 } 84 } 85 swap(t[1],t[k]); 86 sort(t + 2,t + N + 1,cmp); 87 Graham(); 88 ans = Solve(1,cnt); 89 printf("%d\n",ans); 90 return 0; 91 }