Fork me on GitHub

寻找最远点对(凸包求解)

题目来源:https://biancheng.love/contest/41/problem/B/index

 

寻找最远点对

 

题目描述

 

TD走廊里有一关“勇闯梅花桩”,水面上稀稀落落地立着几根柱子。Nova君自认为轻功不错,觉得可以在任意两根柱子之间跳跃,现在他想挑战一次跨越距离最远的两根柱子。请问,最远距离是多少?(由于木桩以横纵坐标形式给出,为了计算方便,避免求平方根,答案只需给出距离的平方即可)

 

输入

 

多组测试数据(组数不超过10),对于每组数据,第一行为一个正整数N,代表梅花桩的个数,接下来N行,每行两个正整数xi, yi分别代表第 i 根桩子的横纵坐标。 (数据在INT范围内)

 

输出

 

对于每组数据,输出一行,为距离最远的两根柱子的距离的平方。

 

输入样例

 

3
1 1
1 2
0 0

 

输出样例

 

5

解题思路:
求出最远的点对,可以化为求出对应的凸包上最远的两个点。

平面凸包 :

 

 定义: 对一个简单多边形来说,如果给定其边界上或内部的任意两个点,连接这两个点的线段上的所有点都被包含在该多边形的边界上或内部的话,则该多边形为凸多边形 。

在解决平面凸包下面介绍了两种算法:

一、  Graham扫描法,运行时间为O(nlgn)。

二、  Jarvis步进法,运行时间为O(nh),h为凸包中的顶点数。


推荐博客http://blog.csdn.net/bone_ace/article/details/46239187
推荐博客http://www.cnblogs.com/jbelial/archive/2011/08/05/2128625.html
给出代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #define INF -110
 5 
 6 using namespace std;
 7 long long i,j,k,n,top,ans;
 8 
 9 struct Node
10 {
11  int x;
12  int y;
13 }no[1000010],stack[1000010];
14 
15 long long dis(Node p1,Node p2)
16 {
17     return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
18 }
19 
20 long long mult(Node p1,Node p2,Node p0)
21 {
22     return ((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
23 }
24 
25 long long cmp(Node a,Node b)
26 {
27     if(mult(a,b,no[0])>0)
28         return 1;
29     else if(mult(a,b,no[0])==0&&dis(a,no[0])<dis(b,no[0]))
30         return 1;
31     return 0;
32 }
33 
34 void work()
35 {
36     k=0;
37     for(i=1; i<n; i++)
38     {
39         if(no[k].y>no[i].y || ((no[k].y == no[i].y) && no[k].x > no[i].x))
40             k = i;
41     }
42     Node tmp;
43     tmp = no[0];
44     no[0] = no[k];
45     no[k] = tmp;
46     sort(no+1,no+n,cmp);
47     top = 2;
48     stack[0] = no[0];
49     stack[1] = no[1];
50     stack[2] = no[2];
51     for(i=3; i<n; i++)
52     {
53         while(top>1 && mult(no[i],stack[top],stack[top-1])>=0)
54             top--;
55         stack[++top] = no[i];
56     }
57 }
58 
59 int main()
60 {
61     while(~scanf("%lld",&n))
62     {
63         for(i=0; i<n; i++)
64             scanf("%lld%lld",&no[i].x,&no[i].y);
65         work();
66         ans=INF;
67         for(i=0; i<=top; i++)
68         {
69             for(j=i+1; j<=top; j++)
70             {
71                 if(ans<dis(stack[i],stack[j]))
72                     ans=dis(stack[i],stack[j]);
73             }
74         }
75         printf("%lld\n",ans);
76     }
77     return 0;
78 }

 



 

posted @ 2015-12-25 00:24  伊甸一点  阅读(2081)  评论(0编辑  收藏  举报