此题链接:点击打开链接
题目大意是给出岛屿的数量n和雷达的覆盖半径d,然后给出n组岛屿坐标,问最少需要多少雷达可以覆盖所有岛屿。
这个题可以换个思路(并没有思路),通过岛的坐标(直角边)和雷达半径(斜边)求出雷达所能覆盖此岛可能所在的区间,算是个区间覆盖问题。这样将区间尾端 按从小到大排序后找到第一个区间的尾端作为第一个雷达的位置,这样才能保证覆盖到最外端的岛屿,遍历一遍所有区间,若区间前端比雷达位置靠后,则雷达无法覆盖, 雷达数加一,新雷达位置为此区间的尾端。
这个题坑不少,首先d可以是负的,这样就没了,y>d也是不可以的,这两种情况要在输入的时候判断一下,除了n,d和一些常用变量是int外,其他都要用double存。
//264K 47MS
//C++ 1126B
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct node
{
double b,d;
}a[1123];
int cmp(node a,node b)
{
return a.d<b.d;
}
int main()
{
int i,n,d,l=0,k;
double x,y;
while(scanf("%d%d",&n,&d)&&(n||d))
{
l++;
k=0;
int sum=1;
for(i=0;i<n;i++)
{
cin>>x>>y;
if(y>d||d<0) //覆盖半径为负或有覆盖不到的点则标记
{
k=1;
}
a[i].b=x-sqrt(d*d-y*y);//记录区间前端位置
a[i].d=x+sqrt(d*d-y*y);//记录区间尾端位置
}
if(k) //出现上面的情况直接输出-1
{
printf("Case %d: -1\n",l);
}
else
{
sort(a,a+n,cmp); //按区间尾端升序排序
double f=a[0].d; //当前雷达位置为第一个区间的尾端
for(i=1;i<n;i++)
{
if(a[i].b>f) //若此雷达不在该区间内
{
sum++; //雷达数加一
f=a[i].d; //更新雷达位置
}
}
printf("Case %d: %d\n",l,sum);
}
}
return 0;
}