假设陆地的海岸线是一条无限延长的直线,海岛是一个个的点,现需要在海岸线上安装雷达,使整个雷达系统能够覆盖到所有的海岛。雷达所能覆盖的区域是以雷达为圆心半径为d的圆,我们用指标坐标系来描述,海岸线就是x轴,现在给出每个海岛的坐标与雷达的半径d,请编写一个程序计算出最少需要多少个雷达才能够将所有海岛全部覆盖?
输入:
输入将会有多组数据,每组数据第一行为n (1<=n<=1000),d,n为海岛个数,d为雷达半径,接下来n行,每行两个数描述海岛坐标。以n==0,d==0表示输入结束
输出:
每组数据对应一行,输出最少需要的雷达个数,如果不能满足,则输出-1,具体格式见样例。
样例输入:
3 2
1 2
-3 1
2 1
1 2
0 2
0 0
样例输出:
Case 1: 2
Case 2: 1
题很坑!大致思路就是把每个点转换为一条条线段,用区间选点的方法做,很坑,具体见代码。
<pre name="code" class="cpp">#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;
struct seg{
double a,b;
}x[1001];//每一条线段
int n;
double d;
bool cmp(seg a,seg b)
{
if(a.b!=b.b)return a.b<b.b;
return a.a>b.a;
}//按照每一条线段的右端点排序
int work(double a,double b,int i)
{
if(b>d||b<-d)return 1;//雷达不能覆盖
double dis=sqrt(d*d-b*b);
x[i].a=a-dis,x[i].b=a+dis;
return 0;
}
int main()
{
int num=0;
while(cin>>n>>d)
{
num++;
int i,cnt=0,f=0,f1;
double j,k;
if(!n&&!d)break;
memset(x,0,sizeof(x));
for(i=1;i<=n;i++)
{
cin>>j>>k;
f1=work(j,k,i);
if(f1)f=1;
}
if(d<0||f)//雷达半径为负数......也是不能到达的
{
cout<<"Case "<<num<<": "<<-1<<endl;
continue;
}
sort(x+1,x+n+1,cmp);
double end=-0x3f3f3f3f;//横坐标要很小....因为..你懂的
for(i=1;i<=n;i++)
{
if(end<x[i].a)
{
end=x[i].b;
cnt++;
}
}
cout<<"Case "<<num<<": "<<cnt<<endl;
}
}