[Luogu] UVA1193 Radar Installation
阿新 • • 發佈:2020-11-24
Description
假設海岸線是一條無限長的直線,陸地位於海岸線的一邊,大海位於海岸線的另一邊。大海中有許多小島。某安全部門為了監視這些島上是否有敵人入侵,打算在海岸線上安裝若干個雷達來檢測島嶼的情況。每個雷達的覆蓋範圍是以雷達中心為圓心,半徑為\(d\)的圓形區域。
我們用平面之間座標系來表示整個區域,海岸線為\(x\)軸,大海位於\(x\)軸上方,陸地位於\(x\)軸下方。為了節約成本,安全部門想使用最少的雷達覆蓋所有的島嶼。現在已知每個島嶼的座標\((x,y)\)和雷達的覆蓋半徑\(d\),你的任務就是計算出能夠覆蓋所有島嶼的最少雷達數量。
Solution
這道題的貪心思路就是對於一個未被覆蓋的海島,肯定是貪心地把雷達放在能覆蓋到它的最右邊的地方。但是排序不是按\(x\)
然後這題要開\(double\),注意實數比較大小會有誤差,要用\(eps\)。
Code
#include <bits/stdc++.h> using namespace std; const double eps = 1e-6; int n, t, bk[1005]; struct node { double x, y, r; }p[1005]; double d; int read() { int x = 0, fl = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') fl = -1; ch = getchar();} while (ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) + ch - '0'; ch = getchar();} return x * fl; } int cmp(node a, node b) { return a.r < b.r || (a.r == b.r && a.y > b.y); } int main() { while (1) { n = read(); scanf("%lf", &d); if ((!n) && (!d)) break; double mx = 0; for (int i = 1; i <= n; i ++ ) { scanf("%lf %lf", &p[i].x, &p[i].y); mx = max(mx, p[i].y); p[i].r = p[i].x + sqrt(d * d - p[i].y * p[i].y); } sort(p + 1, p + n + 1, cmp); t ++ ; printf("Case %d: ", t); if (mx > d) { puts("-1"); continue; } double pos; int res = 0; for (int i = 1; i <= n; i ++ ) { pos = p[i].x + sqrt(d * d - p[i].y * p[i].y); res ++ ; for (int j = i + 1; j <= n; j ++ ) { i = j; if (p[j].y * p[j].y + (pos - p[j].x) * (pos - p[j].x) - d * d > eps) { i -- ; break; } } } printf("%d\n", res); } return 0; }