题目:POJ - 1328
第一次的思路:所有岛屿按x坐标排序,从最左开始,画圆心在x轴上的圆,使得该岛屿在圆的边上,也就是选择圆心尽量靠右的圆。再从第一个没有被该圆覆盖的岛屿开始上述过程。
错误,因为岛屿还有y坐标的影响,会出现这种情况:岛屿i被一个圆覆盖了,但是岛屿i-1位置更高,没有被覆盖。
正确策略:以岛屿为圆心做圆,与x轴所成的弦,就是可以覆盖这个岛屿的雷达的区间。将所有区间去重。
区间去重的时候要注意:是否会影响当前用来作比较的数,比如例题POJ3069就不会,而这道题会,雷达的位置是变化的,要处在所有区间的交集内
28 rx = min(rx, r[i].second);
1 #include <iostream> 2 #include <math.h> 3 #include <algorithm> 4 5 using namespace std; 6 7 int n; 8 int d; 9 pair<int, int> p[1000]; 10 pair<double, double> r[1000]; 11 12 double getDx(int py) { 13 return (double)sqrt((double)(d * d - py * py)); 14 } 15 16 int solve() { 17 int res = 0; 18 for (int i = 0; i < n; i++) { 19 r[i].first = p[i].first - getDx(p[i].second); 20 r[i].second = p[i].first + getDx(p[i].second); 21 } 22 sort(r, r + n); 23 int i = 0; 24 while (i < n) { 25 double rx = r[i].second; 26 i++; 27 while (i < n && (double)(r[i].first) <= rx) { 28 rx = min(rx, r[i].second); 29 i++; 30 } 31 res++; 32 } 33 return res; 34 } 35 36 int main() { 37 int caseNO = 0; 38 while(cin >> n >> d && n!= 0) { 39 caseNO++; 40 int solvable = 1; 41 for (int i = 0; i < n; i++) { 42 cin >> p[i].first; 43 cin >> p[i].second; 44 if (p[i].second > d) { 45 solvable = 0; 46 } 47 } 48 if (solvable) { 49 cout << "Case " << caseNO << ": " << solve() << endl; 50 } 51 else { 52 cout << "Case " << caseNO << ": -1" << endl; 53 } 54 } 55 return 0; 56 }