思路:
关于区间的贪心问题。首先排除 d<=0 或者 某个岛屿的纵坐标大于d的情况。之后以每个island为圆心,d为半径画圆,与x轴产生两个交点,这两个交点构成一个区间。在这个区间内任意位置放置雷达都能覆盖到这个island。对所有这样的区间排序后,从左到右扫描,维护目前放置雷达的位置now_right,设下一个区间的靠左的x坐标为left,靠右的x坐标为right。如果left > now_right,即两个区间没有交集,则在right重新放置一个雷达,并且now_right = right;如果left <= now_right 并且 right <= now_right,相当于下一个区间被包含到当前区间,此时无需重新放置雷达,只要令now_right = right即可,相当于把now_right部位放置的雷达“挪”回到right位置,同时满足了两个区间的需求;如果left <= now_right 并且 right > now_right,则此时now_right放置的雷达就能满足两个区间的要求,同样无需重新放置雷达。
实现:
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 7 struct node 8 { 9 double x, y; 10 }; 11 node a[1005]; 12 int n, d; 13 pair<double, double> p[1005]; 14 15 int main() 16 { 17 int T = 1; 18 while (cin >> n >> d, n || d) 19 { 20 bool flag = true; 21 if (d <= 0) 22 flag = false; 23 for (int i = 0; i < n; i++) 24 { 25 cin >> a[i].x >> a[i].y; 26 if (a[i].y > d) 27 flag = false; 28 } 29 if (!flag) 30 { 31 cout << "Case " << T++ << ": -1" << endl; 32 continue; 33 } 34 for (int i = 0; i < n; i++) 35 { 36 p[i].first = a[i].x - sqrt(d * d - a[i].y * a[i].y); 37 p[i].second = a[i].x + sqrt(d * d -a[i].y * a[i].y); 38 } 39 sort(p, p + n); 40 int cnt = 1; 41 double now_right = p[0].second; 42 for (int i = 1; i < n; i++) 43 { 44 if (p[i].first > now_right) 45 { 46 cnt++; 47 now_right = p[i].second; 48 } 49 else if (p[i].second <= now_right) 50 { 51 now_right = p[i].second; 52 } 53 } 54 cout << "Case " << T++ << ": " << cnt << endl; 55 } 56 return 0; 57 }
1 #include <iostream> 2 #include <cmath> 3 #include <algorithm> 4 using namespace std; 5 const int MAXN = 1005; 6 pair<double, double> p[MAXN]; 7 int square(int x) 8 { 9 return x * x; 10 } 11 bool comp(const pair<double, double> & a, const pair<double, double> & b) 12 { 13 if (a.second != b.second) return a.second < b.second; 14 return a.first < b.first; 15 } 16 int main() 17 { 18 int n, d, Kase = 1; 19 while (cin >> n >> d, n || d) 20 { 21 bool flg = true; 22 for (int i = 0; i < n; i++) 23 { 24 cin >> p[i].first >> p[i].second; 25 if (p[i].second > d) flg = false; 26 double tmp = sqrt(square(d) - square(p[i].second)); 27 double l = p[i].first - tmp, r = p[i].first + tmp; 28 p[i].first = l; p[i].second = r; 29 } 30 if (!flg) { cout << "Case " << Kase++ << ": -1" << endl; continue; } 31 sort(p, p + n, comp); 32 int ans = 1, i = 1; 33 double now = p[0].second; 34 while (i < n) 35 { 36 if (p[i].first > now) { ans++; now = p[i].second; } 37 i++; 38 } 39 cout << "Case " << Kase++ << ": " << ans << endl; 40 } 41 return 0; 42 }