hlg1414安装雷达【贪心】
大意:
如上图:坐标轴上有一些点 然后在x轴上安装雷达 告诉你雷达的最大扫描半径 问你最少用多少个雷达就能把所有的点扫描到
分析:
从每个告诉的点都画一个圆,那么它就会和x轴有两个交点 这两个交点之内的任何一个点都能建立雷达扫描的到
我们把两个点之间看做一条线段
那么问题就转化成了 对于x轴上的一些线段 用最少的点覆盖掉
我们只要把 这些线段按右边界按从小到大排序
那么这些线段就是右边界一次增大的了
若一条线段的后面线段的左边界比该边界小 那么就可以通过覆盖这个点来得到
只要一个标记就可以了
代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 1005; 9 10 struct Node { 11 double x, y; 12 }node[maxn], ans[maxn]; 13 14 double dist(Node n1, Node n2) { 15 return sqrt((n1.x - n2.x) * (n1.x - n2.x) + (n1.y - n2.y) * (n1.y - n2.y) ); 16 } 17 18 int eps(double x) { 19 if(fabs(x) < 1e-6) { 20 return 0; 21 } 22 if(x < 0 ) { 23 return -1; 24 } 25 return 1; 26 } 27 28 bool cmp(Node n1, Node n2) { 29 if(eps(n1.y - n2.y) != 0) { 30 return n1.y < n2.y; 31 } 32 return n1.x < n2.x; 33 } 34 int vis[maxn]; 35 36 int main() { 37 int n; double r; 38 double a, b; 39 int t = 1; 40 while(scanf("%d %lf",&n, &r) ) { 41 if(n == 0 && eps(r) == 0 ) break; 42 int cnt = 0; 43 for(int i = 0; i < n; i++) { 44 scanf("%lf %lf", &a, &b); 45 if(eps(r - b) != -1) { 46 node[cnt++] = (Node) { a, b }; 47 } 48 } 49 for(int i = 0; i < cnt; i++) { 50 ans[i].x = node[i].x - sqrt(r * r - node[i].y * node[i].y); 51 ans[i].y = node[i].x + sqrt(r * r - node[i].y * node[i].y); 52 } 53 sort(ans, ans + cnt, cmp); 54 int ans_cnt = 0; 55 memset(vis, 0, sizeof(vis)); 56 for(int i = 0; i < cnt; i++) { 57 if(vis[i]) continue; 58 ans_cnt++; 59 for(int j = i + 1; j < cnt; j++) { 60 if(vis[j]) continue; 61 if(eps(ans[j].x - ans[i].y) != 1) { 62 vis[j] = 1; 63 } 64 } 65 vis[i] = 1; 66 } 67 if(cnt != n) { 68 ans_cnt = -1; 69 } 70 printf("Case %d: %d\n",t++, ans_cnt); 71 } 72 return 0; 73 }