帮我用C语言实现查找最近点 Description 给定一组二维点,每个点对应一个字符。给定任意一个位置,输出距离其最近点到它的距离。 【注意】输出要求:四位小数,输出4位小数的方式:printf("%.4f\n", x),为了保证精度,请大家用double进行输入和计算。 Input 第一行两个数:点的个数N以及查询的个数M 接下来N行,每行2个浮点数和一个字符,代表点的坐标以及其对应的字符 接下来M行,每行2个浮点数,代表希望查询的位置 数据范围满足 N<=10000, M<=10000 Output M行,每行为点集中距离查询位置最近的距离,精确到小数点后4位。
时间: 2024-02-16 11:00:33 浏览: 89
去掉重复的字符串及在第一个字符串中删除在第二个字符串中出现的字符
以下是基于kd-tree算法实现的C语言代码,实现查找最近点:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAXN 10005
typedef struct Point {
double x, y;
char c;
} Point;
typedef struct Node {
Point p;
struct Node *lc, *rc;
} Node;
int n, m;
Point points[MAXN];
Node *root;
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;
}
void build_kd_tree(Node **p, int l, int r, int depth) {
if (l >= r) return;
int mid = l + r >> 1;
*p = (Node *)malloc(sizeof(Node));
(*p)->p = points[mid];
build_kd_tree(&(*p)->lc, l, mid, depth + 1);
build_kd_tree(&(*p)->rc, mid + 1, r, depth + 1);
if (depth & 1)
qsort(&points[l], r - l, sizeof(Point), cmp);
else
qsort(&points[l], r - l, sizeof(Point), cmp);
}
double dist(Point *p1, Point *p2) {
double dx = p1->x - p2->x, dy = p1->y - p2->y;
return sqrt(dx * dx + dy * dy);
}
double query_kd_tree(Node *p, Point *q, double d, int depth) {
if (!p) return d;
double d1 = dist(&p->p, q);
if (d1 < d) d = d1;
double dl = query_kd_tree(p->lc, q, d, depth + 1);
double dr = query_kd_tree(p->rc, q, d, depth + 1);
if (depth & 1) {
if (q->y - d < p->p.y)
d = fmin(d, dl);
if (q->y + d > p->p.y)
d = fmin(d, dr);
} else {
if (q->x - d < p->p.x)
d = fmin(d, dl);
if (q->x + d > p->p.x)
d = fmin(d, dr);
}
return d;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; ++i)
scanf("%lf%lf%*c%c", &points[i].x, &points[i].y, &points[i].c);
build_kd_tree(&root, 0, n, 0);
for (int i = 0; i < m; ++i) {
Point q;
scanf("%lf%lf", &q.x, &q.y);
printf("%.4f\n", query_kd_tree(root, &q, 1e10, 0));
}
return 0;
}
```
该算法中,首先将二维平面上的点按照x轴或y轴的大小排序,然后以中间点为根节点,递归构建kd-tree。在查询过程中,根据当前节点所在深度的奇偶性,判断需要遍历左子树或右子树,并且在遍历过程中,通过比较当前节点和查询点之间的距离和当前最小距离,来决定是否需要更新最小距离。
阅读全文