题目大意(vj上的翻译版本)
假定海岸线是无限长的直线。陆地位于海岸线的一侧,海洋位于另一侧。每个小岛是位于海洋中的一个点。对于任何一个雷达的安装 (均位于海岸线上),只能覆盖 d 距离,因此海洋中的小岛被雷达安装所覆盖的条件是两者间的距离不超过 d 。 我们使用卡笛尔坐标系,将海岸线定义为 x 轴。海洋的一侧位于 x 轴上方,陆地的一侧位于下方。给定海洋中每个小岛的位置,并给定雷达安装的覆盖距离,您的任务是写一个程序,找出雷达安装的最少数量,使得所有的小岛都被覆盖。注意:小岛的位置以它的 x-y 坐标表示。
解法
最初看到这个题也是一头雾水,根本无从下手,看了看网上的老哥的题解。发现要用逆向思维去做。也就是说这个要用岛去来找雷达,最终化成区间选点问题!!!
怎么把圆化成线性区间以及解法?
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
double cal(double a,double b)
{
return sqrt(b*b-a*a);
}
struct node
{
double l,r;
}num[10000];
bool cmp(node a,node b)
{
return a.r==b.r?a.l>b.l:a.r<b.r;
}
int main()
{
/*ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);*/
int n,d,cnt=0;
while(cin>>n>>d&&n&&d)
{
int f=0;
for(int i=0;i<n;i++)
{
double t1,t2;
cin>>t1>>t2;
if(t2>d)
f=1;
double delta=cal(t2,d);
num[i].l=t1-delta;
num[i].r=t1+delta;
}
sort(num,num+n,cmp);
double now=num[0].r;
int ans=1;
for(int i=1;i<n;i++)
if(num[i].l>now)
{
ans++;
now=num[i].r;
}
printf("Case %d: ",++cnt);
if(f)
cout<<-1<<"\n";
else
cout<<ans<<"\n";
}
}