给出一些整数对,它们表示平面上的点,求所有这些点中距离最近的两个点。 输入格式: 测试数据有多组。对于每组测试,先输入一个整数N,表示点的个数,再输入N个点(以两个整数表示横纵坐标)。若N为0,则表示输入结束。 输出格式: 对于每组测试,输入所有点中距离最短的两点,格式为“(a,b) (c,d)”,其中,a,b,c,d分别表示第一、二个点的横纵坐标。若有多个点对之间距离最短,以先输入者优先(如第一组样例所示)。
时间: 2024-03-20 12:39:38 浏览: 200
以下是使用分治法求解的 C++ 代码示例:
```c++
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 100010;
struct Point
{
double x, y;
}p[N];
bool cmp(Point a, Point b)
{
return a.x < b.x;
}
bool cmp2(Point a, Point b)
{
return a.y < b.y;
}
double dist(Point a, Point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
double merge(Point p[], int l, int r, double d)
{
if (l >= r) return d;
int mid = l + r >> 1;
double d1 = merge(p, l, mid, d), d2 = merge(p, mid + 1, r, d);
double d0 = min(d1, d2);
int cnt = 0;
for (int i = l; i <= r; i++)
if (fabs(p[i].x - p[mid].x) < d0)
p[cnt++] = p[i];
sort(p, p + cnt, cmp2);
for (int i = 0; i < cnt; i++)
for (int j = i + 1; j < cnt && p[j].y - p[i].y < d0; j++)
d0 = min(d0, dist(p[i], p[j]));
return d0;
}
int main()
{
int n;
while (cin >> n, n)
{
for (int i = 0; i < n; i++) cin >> p[i].x >> p[i].y;
sort(p, p + n, cmp);
double d = merge(p, 0, n - 1, 1e20);
Point a, b;
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n && p[j].x - p[i].x < d; j++)
{
double dis = dist(p[i], p[j]);
if (dis < d)
{
d = dis;
a = p[i], b = p[j];
}
}
printf("(%.0f,%.0f) (%.0f,%.0f)\n", a.x, a.y, b.x, b.y);
}
return 0;
}
```
注意事项:
1. 每次递归结束后,需要将左右两部分的点按照纵坐标排序,以便计算跨越中线的点对。
2. 注意浮点数比较时要使用 fabs 函数取绝对值。
阅读全文