1 条题解
-
0
简单解题思路
问题描述
给定三维空间中的
n
个点,每个点有一个类别标识(id
)。要求找到一个距离r
,使得在以r
为半径的范围内:- 不同类别的点尽可能分离(即不同类别的点对数量最大化);
- 同类别的点尽可能聚集(即同类别的点对数量最小化)。
最终输出满足条件的最大点对数量
num
和对应的距离r
(取平方根后的实际距离)。核心思路
-
计算所有点对距离:
- 预处理所有点对之间的欧氏距离平方(避免开方运算,提高效率)。
-
排序所有距离:
- 将计算出的所有点对距离按从小到大排序。
-
滑动窗口统计:
- 从小到大遍历每个距离
dis[i]
,动态维护当前距离下的点对状态:- 如果两点类别不同,减少它们的计数(模拟分离);
- 如果两点类别相同,增加它们的计数(模拟聚集)。
- 统计当前距离下满足条件的点对数量
cnt
。
- 从小到大遍历每个距离
-
记录最优解:
- 在遍历过程中,记录使
cnt
最大的距离r
及其对应的num
。
- 在遍历过程中,记录使
关键步骤
-
输入处理:
- 读取每个点的坐标
(x, y, z)
和类别id
。
- 读取每个点的坐标
-
距离计算与排序:
- 计算所有点对的欧氏距离平方,并排序。
-
动态统计:
- 使用滑动窗口方法,动态更新每个距离下的点对状态。
- 维护当前距离下的最优解
(num, r)
。
-
输出结果:
- 输出最大点对数量
num
和对应的实际距离sqrt(r)
。
- 输出最大点对数量
总结
- 核心算法:暴力枚举 + 排序 + 滑动窗口统计。
- 适用场景:空间聚类分析、距离阈值优化。
- 优化点:通过距离平方避免浮点运算,利用排序简化统计过程。
#include <cstdio> #include <algorithm> #include <cmath> // 定义节点结构体 struct node { int id, x, y, z; } sta[1005]; // 定义距离结构体 struct node1 { int be, fin, len; bool operator < (const node1& a) const{ return len < a.len; } } dis[1005*1005]; int numb[1005]; // 计算两点之间距离的函数 int getdis(int a, int b); // 计算平方的函数 int pw(int x); int main() { int n; while (scanf ("%d", &n) != EOF) { int k = 0, x, y, z, p; for (int i = 1; i <= n; i++) { scanf ("%d%d%d%d", &x, &y, &z, &p); sta[i] = (node){p, x, y, z}; numb[i] = 1; } for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++) { dis[++k].be = i; dis[k].fin = j; dis[k].len = getdis(i, j); } int r = 0, num = 0, cnt = 0; // 使用 std::sort 函数,明确指定迭代器范围 std::sort(dis + 1, dis + 1 + k); for (int i = 1; i <= k; i++) { int xx = dis[i].be, yy = dis[i].fin; if (sta[xx].id != sta[yy].id) { numb[xx]--; numb[yy]--; if (numb[xx] == -1) cnt++; if (numb[yy] == -1) cnt++; } else { numb[xx]++; numb[yy]++; if (numb[xx] == 0) cnt--; if (numb[yy] == 0) cnt--; } if (i != k && dis[i].len == dis[i + 1].len) continue; if (num < cnt) { num = cnt; r = dis[i].len; } } printf ("%d\n%.4f\n", num, std::sqrt(r * 1.0)); } return 0; } // 计算平方的函数实现 int pw(int x) { return x * x; } // 计算两点之间距离的函数实现 int getdis(int a, int b) { int sum = pw(sta[a].x - sta[b].x) + pw(sta[a].y - sta[b].y) + pw(sta[a].z - sta[b].z); return sum; }
- 1
信息
- ID
- 902
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者