题目描述
假设海岸线是一条无限延伸的直线,它的一侧是陆地,另一侧是海洋,每一座小岛是在海面上的一个点。
雷达必须安装在陆地上(包括海岸线),并且每个雷达都有相同的扫描范围 d(半径)。你的任务是建立尽量少的雷达站,使所有小岛都在扫描范围之内。
数据使用笛卡尔坐标系,定义海岸线为 x 轴。在 x 轴上方为海洋,下方为陆地。
输入格式
第一行包括 2 个整数 n 和 d,n 是岛屿数目,d 是雷达扫描范围。
接下来 n 行为岛屿坐标。
输出格式
一个整数表示最少需要的雷达数目,若不可能覆盖所有岛屿,输出 −1 。
样例 #1
样例输入 #1
3 2
1 2
-3 1
2 1
样例输出 #1
2
提示
n≤1000,d≤20000
∣xi∣≤2×106,0≤yi≤20000
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct node
{
int l,r;
}a[1010];
bool cmp(node n1,node n2)
{
return n1.r<n2.r;
}
int main()
{
int n,d;
cin>>n>>d;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>x>>y;
if(y>d)
{
cout<<-1;
return 0;
}
a[i].l=x-sqrt(d*d-y*y);
a[i].r=x+sqrt(d*d-y*y);
}
sort(a+1,a+n+1,cmp);
int pre=a[1].r,cnt=1;
for(int i=2;i<=n;i++)
if(pre<a[i].l)
{
pre=a[i].r;
cnt++;
}
cout<<cnt;
return 0;
}
这道题乍一看,像是一个区间类的贪心问题。但是仔细一看,它是一道三星题!难点有两个:
1.他说“雷达必须安装在陆地上(包括海岸线)”,而“小岛是在海面上的”,所以肯定雷达离小岛越近越好,所以雷达必须都安装在海岸线上。
2.他给出了雷达笼罩范围的半径,又给出了小岛的二维坐标,可以将二维坐标转化成一个区间,代表雷达要装在此区间内才能笼罩住该小岛。具体公式根据勾股定理推出:左端点:a[i].l=x-sqrt(d*d-y*y);右端点:a[i].r=x+sqrt(d*d-y*y);