题干
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 Cyberground, the position of each toy is fixed, and the ring is carefully designed so it can only encircle one toy at a time. On the other hand, to make the game look more attractive, the ring is designed to have the largest radius. Given a configuration of the field, you are supposed to find the radius of such a ring. Assume that all the toys are points on a plane. A point is encircled by the ring if the distance between the point and the center of the ring is strictly less than the radius of the ring. If two toys are placed at the same point, the radius of the ring is considered to be 0.
Input 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 (could be decimal). The input is terminated by N = 0.
Output For each test case, print in one line the radius of the ring required by the Cyberground manager, accurate up to 2 decimal places
翻译
你曾经在操场上玩过quoit吗?Quoit是一种向一些玩具投掷扁平圆环的游戏,所有被包围的玩具都会获得奖励。在Cyberground领域,每个玩具的位置都是固定的,圆环经过精心设计,一次只能包围一个玩具。另一方面,为了让游戏看起来更有吸引力,环被设计成具有最大的半径。给定一个场的配置,你应该找到这样一个环的半径。假设所有的玩具都是平面上的点。如果一个点和环的中心之间的距离严格小于环的半径,则该点被环包围。如果两个玩具放在同一点上,则认为环的半径为0。
输入输入由几个测试用例组成。对于每种情况,第一行都包含一个整数N(2<=N<=100000),即字段中玩具的总数。接下来是N行,每行包含一对(x,y),它们是玩具的坐标(可以是十进制)。输入以0终止。
输出对于每个测试用例,在一行中打印Cyberground管理器所需的环的半径,精确到小数点后2位
简言之,求输入数据对所构成平面点集中,距离最近点间距离的一半(半径R)。
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
| 以文本方式显示
| 1秒 | 64M | 0 |
思路:
分治法就不说了,这次尝试了一下非分治算法,据说时间复杂度和分治法一样,但是不知为什么死在第二个测试用例上了,先把错误的代码交上来嘿嘿
代码:
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <set>
const int N = 200005;
double ans = 1e20;
using namespace std;
struct point
{
double x, y;
point(double x = 0, double y = 0) : x(x), y(y) {}
};
struct cmp_x
{
bool operator()(const point &a, const point &b) const
{
return a.x < b.x || (a.x == b.x && a.y < b.y);
}
};
struct cmp_y
{
bool operator()(const point &a, const point &b) const { return a.y < b.y; }
};
void upd_ans(const point &a, const point &b)
{
double dist = sqrt(pow((a.x - b.x), 2) + pow((a.y - b.y), 2));
if (ans > dist)
ans = dist;
}
point a[N];
multiset<point, cmp_y> s;
int main()
{
int n;
while (cin >> n && n != 0)
{
s.clear();
for (int i = 0; i < n; i++)
scanf("%lf%lf", &a[i].x, &a[i].y);
sort(a, a + n, cmp_x());
for (int i = 0, l = 0; i < n; i++)
{
while (l < i && a[i].x - a[l].x >= ans)
s.erase(s.find(a[l++]));
for (auto it = s.lower_bound(point(a[i].x, a[i].y - ans));
it != s.end() && it->y - a[i].y < ans; it++)
upd_ans(*it, a[i]);
s.insert(a[i]);
}
printf("%.2lf\n", ans / 2.0);
}
return 0;
}