acwing星空之夜题解
时间: 2025-06-23 11:30:01 浏览: 14
### AcWing 1402. 星空之夜 题目解析
#### 问题描述
给定平面上的一些星星的位置,定义一个星群是由若干颗星星组成的集合。对于每一个可能的星群,计算其内部任意两颗不同星星之间欧几里得距离之和作为该星群的一个特征值g。
#### 数据结构设计
为了高效处理这个问题,可以采用哈希表存储每种形状对应的总距离和,并利用组合数原理减少重复计算。具体来说:
- 使用 `unordered_map` 来记录每个不同的相对位置向量及其出现次数。
- 对于每一组新的点集,先将其转换成标准化的形式再查找是否存在相同的模式;如果存在,则直接累加已有的计数值到当前答案中去[^1]。
#### 关键算法逻辑
遍历所有输入坐标对,构建出所有的边(即两点间连线),并按照一定规则规范化表示这些边的方向与长度。接着统计相同类型的边的数量,最后依据组合公式求解最终的结果。
```cpp
#include <bits/stdc++..h>
using namespace std;
const int N = 1e5 + 7;
typedef long double ld;
pair<ld, ld> p[N];
map<pair<int, pair<long long, long long>>, int> mp;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n; cin >> n;
for (int i = 1; i <= n; ++i) cin >> p[i].first >> p[i].second;
sort(p + 1, p + n + 1);
for (int i = 1; i <= n; ++i){
map<pair<long long, long long>, int> tmp;
for (int j = i + 1; j <= n; ++j){
auto dx = round((p[j].first - p[i].first)*1e9), dy = round((p[j].second - p[i].second)*1e9);
if (!dx && !dy) continue;
ll d = __gcd(abs(dx), abs(dy));
dx /= d, dy /= d;
tmp[{dx, dy}]++;
}
for(auto &it : tmp)
mp[{n, it.first}] += it.second * (it.second - 1) / 2;
for(int j = i + 1; j <= n; ++j){
auto dx = round((p[j].first - p[i].first)*1e9), dy = round((p[j].second - p[i].second)*1e9);
if(!dx&&!dy)continue;
ll d=__gcd(abs(dx),abs(dy));dx/=d;dy/=d;
mp[{n,{dx,dy}}]+=tmp[{dx,dy}];
}
}
long long res = 0;
for (auto& [_, v] : mp) res += v;
printf("%lld\n",res);
}
```
此代码实现了上述提到的方法论,在实际应用时还需要注意精度控制以及边界条件等问题。
阅读全文
相关推荐











