The Closest Pair Problem
Input: standard input
Output: standard output
Time Limit: 8 seconds
Memory Limit: 32 MB
Given a set of points in a two dimensional space, you will have to find the distance between the closest two points.
Input
The input file contains several sets of input. Each set of input starts with an integer N (0<=N<=10000), which denotes the number of points in this set. The next N line contains the coordinates of N two-dimensional points. The first of the two numbers denotes the X-coordinate and the latter denotes the Y-coordinate. The input is terminated by a set whose N=0. This set should not be processed. The value of the coordinates will be less than 40000 and non-negative.
Output
For each set of input produce a single line of output containing a floating point number (with four digits after the decimal point) which denotes the distance between the closest two points. If there is no such two points in the input whose distance is less than 10000, print the line INFINITY.
Sample Input
30 0
10000 10000
20000 20000
5
0 2
6 67
43 71
39 107
189 140
0
Sample Output
INFINITY36.2215
(World Final Warm-up Contest, Problem setter: Shahriar Manzoor)
“Generally, a brute force method has only two kinds of reply, a) Accepted b) Time Limit Exceeded.”
題意:給出N個點,找出這N個點中距離最近的點對。
思路:直接暴力的話,肯定超時,一開始想到使用分治,但是不確定,後來看了下網上人的解法,確實是使用分治,首先我們把座標按x升序進行排列,然後定義L、R分別爲區間的左右端點(L、R均代表點的標號),mid爲區間中點,我們可以先分別暴力求出在[L,mid]、[mid,R]中最短的線段,不妨設其爲min,當然最短線段還可能是兩個點分別在兩個區間之中,但如果存在這樣的最短線段,那麼線段的兩個端點一定會在區間[a,b]中,並且x[mid]-x[a]>=min,x[b]-x[mid]>=min,因爲兩點之間的距離大於等於兩點橫座標差的絕對值。
代碼:
#include<iostream>
#include<algorithm>
#include<cmath>
#include<iomanip>
using namespace std;
class Node
{
public:
double x,y;
}node[10010];
bool cmp(Node s1,Node s2)
{
return s1.x<s2.x;
}
double distance(Node s1,Node s2)
{
return sqrt((s1.x-s2.x)*(s1.x-s2.x)+(s1.y-s2.y)*(s1.y-s2.y));
}
double dis(int left,int right)
{
if(left==right) return 100000000.0;
if(right-left==1) return distance(node[left],node[right]);
int mid,i,j,k;
double d,cnt;
mid=(left+right)/2;
d=min(dis(left,mid),dis(mid,right));
for(i=mid-1;i>=left&&node[mid].x-node[i].x<d;i--)
{
for(j=mid+1;j<=right&&node[j].x-node[mid].x<d;j++)
{
cnt=distance(node[j],node[i]);
if(cnt<d) d=cnt;
}
}
return d;
}
int main()
{
int num;
while(cin>>num&&num)
{
int i;
for(i=0;i<num;i++)
{
cin>>node[i].x>>node[i].y;
}
sort(node,node+num,cmp);
double mindis=dis(0,num-1);
if(mindis<10000.0)
cout<<fixed<<setprecision(4)<<mindis<<endl;
else
cout<<"INFINITY"<<endl;
}
return 0;
}