题目描述 Description |
Have you ever played quoit in a playground? Quoit is a game in which flat rings are pitched at some toys, with all the toys encircled awarded. In the field of Assume that all |
输入描述 Input Description |
The input consists of several test cases. For each case, the first line contains an integer N (2 <= N <= 100,000), the total number of toys in the field. Then N lines follow, each contains a pair of (x, y) which are the coordinates of a toy. The input is terminated by N = 0. |
输出描述 Output Description |
For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places. |
样例输入 Sample Input |
2 0 0 1 1 2 1 1 1 1 3 -1.5 0 0 0 0 1.5 0 |
样例输出 Sample Output |
0.71 0.00 0.75 |
数据范围及提示 Data Size & Hint |
之前的一些废话:是时候准备会考了。。
题解:求最近点对。首先把平面划分成两个部分,递归求出两个部分的答案为ans,然后,把离分割线距离小于ans/2的点一左一右算距离更新ans.
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long LL; #define mem(a,b) memset(a,b,sizeof(a)) typedef pair<int,int> PII; const int maxn=100010; const double oo=2147483647; struct Point { double x,y; Point() {} Point(double _1,double _2):x(_1),y(_2){} bool operator < (const Point &s)const { if(x==s.x)return y<s.y; return x<s.x; } }p[maxn]; int n;double x,y; double dis(double a,double b,double c,double d){ return sqrt((c-a)*(c-a)+(d-b)*(d-b)); } double mdis(int l,int r) { if(l==r)return 0; if(l+1==r)return dis(p[l].x,p[l].y,p[r].x,p[r].y); double ret=oo; int mid=(l+r)>>1; ret=min(mdis(l,mid),mdis(mid,r)); for(int i=mid-1;i>=l && p[mid].x-p[i].x<ret;i--) for(int j=mid+1;j<=r && p[j].x-p[mid].x<ret && fabs(p[i].y-p[j].y)<ret;j++) ret=min(ret,dis(p[i].x,p[i].y,p[j].x,p[j].y)); return ret; } int main() { while(scanf("%d",&n)!=EOF && n) { for(int i=0;i<n;i++)scanf("%lf%lf",&x,&y),p[i]=Point(x,y); sort(p,p+n); printf("%.2lf\n",mdis(0,n-1)/2); for(int i=0;i<n;i++)p[i]=Point(0,0); } return 0; }
总结: