原题传送:http://poj.org/problem?id=1328
贪心。
每个岛屿在海岸线上都有一个雷达覆盖区间[x - sqrt(r2 - y2), x + sqrt(r2 - y2)],将这些区间按左区间从小到大排序,选择第一个区间,然后在后面找能够重叠的区间,如果能够重叠,那么更新该区间的右端点(取小的),遍历一遍就完事儿了。
(ps:有时候调了精度反而会wa)
View Code
1 #include <stdio.h> 2 #include <math.h> 3 #include <string.h> 4 #include <algorithm> 5 #define N 1005 6 7 const double eps = 1e-8; 8 9 struct node 10 { 11 double x, y; 12 }e[N]; 13 14 struct nd 15 { 16 double s, t; 17 bool operator < (const nd &tmp) const 18 { 19 return s < tmp.s; 20 } 21 }a[N]; 22 23 int main() 24 { 25 double r; 26 int n, i, flag, cas = 1, cnt; 27 while(scanf("%d%lf", &n, &r)) 28 { 29 if(n == 0 && r < eps) 30 break; 31 for(flag = i = 0; i < n; i ++) 32 { 33 scanf("%lf%lf", &e[i].x, &e[i].y); 34 if(e[i].y > r) 35 flag = 1; 36 } 37 if(flag == 1 || r < 0) 38 { 39 printf("Case %d: -1\n", cas ++); 40 continue; 41 } 42 for(i = 0; i < n; i ++) 43 { 44 a[i].s = e[i].x - sqrt(r * r - e[i].y * e[i].y); 45 a[i].t = e[i].x + sqrt(r * r - e[i].y * e[i].y); 46 47 } 48 49 std::sort(a, a + n); 50 51 double s = a[0].s; 52 double t = a[0].t; 53 for(cnt = i = 1; i < n; i ++) 54 { 55 if((a[i].s >= s && a[i].s <= t) || (a[i].t >= s && a[i].t <= t)) // 不调精度才AC 56 { 57 t = std::min(t, a[i].t); 58 } 59 else 60 { 61 cnt ++; 62 s = a[i].s; 63 t = a[i].t; 64 } 65 } 66 printf("Case %d: %d\n", cas ++, cnt); 67 } 68 return 0; 69 }