POJ 1328 Radar Installation-放置雷达
问题:
就是给出n个海岛的坐标和雷达的半径d,雷达只能沿着x轴放置,求出能把所有海岛都覆盖,所需要的最小雷达数。
如果不能满足输出 -1.
n d 为0 0 时结束。
输入:
3 2 1 2 -3 1 2 1 1 2 0 2 0 0
输出:
Case 1: 2 Case 2: 1
分析:
因为雷达的圆心只能在x轴上,所以可以根据每个海岛的坐标、圆的半径,求出能覆盖该海岛的圆的圆心所在的区间。。
把每个海岛的区间都求出来,
然后按照Lelf 或者 Right 从小到大 排序都可以(我是按照Left排序)。
根据贪心原则,第一个雷达一定放在第一个区间的最右端点。让圆的范围尽可能的向右。
如果下一个区间的左端点在雷达的右边,那么sum++,并且雷达更新为这一个区间的右端点。
如果下一个区间的左端点在雷达的左边,sum不变,雷达不变。
如果下一个区间的左端点在雷达的左边,并且右端点也在雷达的左边,那么显然这时候的雷达不能覆盖这个小岛,需要把雷达更新为这个区间的右端点,sum不变。
注意!!!计算后的坐标是会有小数的!!!WA了好几次。
#include <cmath> #include <cstdio> #include <algorithm> #include <iostream> using namespace std; struct Node { double Left,Right; }s[1010]; bool cmp(Node x,Node y) { return x.Left < y.Left; } int main() { int n,d; int time = 0; while(cin>>n>>d && (n != 0 || d != 0)) //这个n d不同时0的条件错了几次,刚开始写成&&了,那样的话是都不能为0。 { time ++; double x,y; double l; int p = 1; for(int i = 0;i < n;i ++) { cin>>x>>y; if(y > d && p) { p = 0; } else //存能覆盖该小岛的圆心所在的区间 { l = sqrt(d*d*1.0 - y*y); s[i].Left = x - l; s[i].Right = x + l; } } if(p) { int sum = 1; sort(s,s + n,cmp); double now = s[0].Right; for(int i = 1;i < n;i ++) { if(s[i].Left > now) { sum ++; now = s[i].Right; } else if(s[i].Right < now) { now = s[i].Right; } } cout<<"Case "<<time<<": "<<sum<<endl; } else cout<<"Case "<<time<<": -1"<<endl; } return 0; }