雷达安装(贪心)
雷达安装
题目描述:
假定海岸线是一条无限延伸的直线,陆地在海岸线的一边,大海在另一侧。海中有许多岛屿,每一个小岛我们可以认为是一个点。现在要在海岸线上安装雷达,雷达的覆盖范围是d,也就是说大海中一个小岛能被安装的雷达覆盖,那么它们之间的距离最大为d。
我们使用平面直角坐标系,定义海岸线是x轴,大海在x轴上方,陆地在下方。给你海中每一个岛屿的坐标位置(x,y)和要安装的雷达所覆盖的范围d,你的任务是写一个程序计算出至少安装多少个雷达能将所有的岛屿覆盖。
输入描述:
第一行两个整数n(1≤n≤100000)和d,分别表示海中岛屿的数目和雷达覆盖的范围半径d。
接下来n行,每行两个整数,表示每个岛屿的坐标位置(x,y)。
输出描述:
一行一个整数,即能将所有岛屿全部覆盖至少安装的雷达个数,如果无解则输出“-1”。
样例输入:
3 2
1 2
-3 1
2 1
样例输出:
2
数据范围及提示:
(1≤n≤100000)
注意会输出-1
思路:
贪心思想
尽量使岛屿位于圆的边上,所以与处理一下:在图形中就是计算出以d为半径,p2为圆心的圆与x轴的交点(只处理左边的),记为点m。
然后算一下p3与m的距离,如果大于d,则ans++。
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=100010;
struct node
{
int x;
int y;
double z;
bool operator < (node tmp)const
{
return tmp.z>z;
}
}a[maxn];
int n,d,ans=1;
int main()
{
cin>>n>>d;
for(int i=1;i<=n;i++)
{
cin>>a[i].x>>a[i].y;
if(a[i].y>d)//判断-1情况
{
cout<<-1;
return 0;
}
a[i].z=double(a[i].x)+sqrt(double(d*d)-double(a[i].y*a[i].y));//处理与x轴交点坐标
}
sort(a+1,a+n+1);//排序
double tmp=a[1].z;
for(int i=2;i<=n;i++)//统计雷达个数
if((a[i].x-tmp)*(a[i].x-tmp)+a[i].y*a[i].y>d*d)
ans++,tmp=a[i].z;
cout<<ans;//输出
return 0;
}