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;
}