發射器位於 (x₀,y₀),半徑 r,可旋轉半圓覆蓋區域。給定 N (≤150) 個點,求半圓旋轉後最多能覆蓋多少點。邊界上的點算覆蓋。
struct Point { double x, y; };
Point trans;
double r;
vector angles;
double dist(Point a, Point b) {
return hypot(a.x-b.x, a.y-b.y);
}
int main() {
while (cin >> trans.x >> trans.y >> r, r >= 0) {
int n; cin >> n;
angles.clear();
for (int i = 0; i < n; ++i) {
Point p; cin >> p.x >> p.y;
if (dist(p, trans) <= r + 1e-9) { // 浮點誤差
double ang = atan2(p.y - trans.y, p.x - trans.x);
if (ang < 0) ang += 2*M_PI;
angles.push_back(ang);
}
}
sort(angles.begin(), angles.end());
int m = angles.size();
for (int i = 0; i < m; ++i) angles.push_back(angles[i] + 2*M_PI);
int ans = 0;
for (int i = 0, j = 0; i < m; ++i) {
while (j < i+m && angles[j] - angles[i] <= M_PI + 1e-9) ++j;
ans = max(ans, j - i);
}
cout << ans << '\n';
}
}
| 問題 | 處理 |
|---|---|
| 浮點誤差 | 距離比較加 `1e-9`,角度比較加 `1e-9` |
| 邊界點 | 題目明確「邊界算內」,`≤ r` 和 `≤ π` 直接包含 |
| 無有效點 | angles 為空,ans=0 正確 |
| 精度 | 用 `atan2` 而非 `acos`,避免定義域錯誤 |
若發射器也可移動,問題變為「最小覆蓋圓」或「最大空圓」,屬於更複雜的計算幾何問題。