设P={(x 1 ,y 1 ),(x 2 ,y 2 ),⋯,(x n ,y n )}是平面上散列的n个点的集合。请编写程序找出集合中距离最近的点对。严格地说,相同距离的最近点对可能不止一对,为了简单期间只找出第一对最近点对即可。 输入格式: 输入第一行给出一个正整数n,表示平面上的点数。随后n行,每行给出一个实数对,每个实数对表示一个点的纵横坐标值,其中第1数表示横坐标,第2数表示纵坐标。 输出格式: 输出最近点对中两个点的坐标和它们之间的距离。如果 x1+y1<=x2+y2则按 (x1,y1),(x2,y2),miniDist=Distance 输出结果,否则按 (x2,y2),(x1,y1),miniDist=Distance 输出结果。 其中x1,y1,x2,y2是保留两位小数的实数,Distance是保留3位小数的实数 用c语言
时间: 2024-02-28 12:56:23 浏览: 117
以下是C语言的代码实现,使用分治算法求解最近点对问题。
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXN 100010
#define INF 1e20
typedef struct Point {
double x, y;
} Point;
int cmp(const void *a, const void *b) {
Point *p1 = (Point *)a;
Point *p2 = (Point *)b;
if (p1->x != p2->x) return p1->x > p2->x ? 1 : -1;
return p1->y > p2->y ? 1 : -1;
}
double min(double a, double b) {
return a < b ? a : b;
}
double dist(Point p1, Point p2) {
return sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2));
}
double closest(Point *p, int left, int right) {
if (left == right) return INF;
if (left + 1 == right) return dist(p[left], p[right]);
int mid = (left + right) / 2;
double d = min(closest(p, left, mid), closest(p, mid+1, right));
Point *strip = (Point *)malloc(sizeof(Point) * (right - left + 1));
int cnt = 0;
for (int i = left; i <= right; i++) {
if (fabs(p[i].x - p[mid].x) < d) strip[cnt++] = p[i];
}
qsort(strip, cnt, sizeof(Point), cmp);
for (int i = 0; i < cnt; i++) {
for (int j = i+1; j < cnt && strip[j].y - strip[i].y < d; j++) {
double d2 = dist(strip[i], strip[j]);
if (d2 < d) d = d2;
}
}
free(strip);
return d;
}
int main() {
int n;
scanf("%d", &n);
Point *p = (Point *)malloc(sizeof(Point) * n);
for (int i = 0; i < n; i++) {
scanf("%lf%lf", &p[i].x, &p[i].y);
}
qsort(p, n, sizeof(Point), cmp);
double d = closest(p, 0, n-1);
printf("(%.2lf,%.2lf),(%.2lf,%.2lf),%.3lf\n", p[0].x, p[0].y, p[1].x, p[1].y, d);
free(p);
return 0;
}
```
算法的时间复杂度为O(nlogn)。
阅读全文