AcWing 雷达设备
Description
假设海岸是一条无限长的直线,陆地位于海岸的一侧,海洋位于另外一侧。
每个小岛都位于海洋一侧的某个点上。
雷达装置均位于海岸线上,且雷达的监测范围为d,当小岛与某雷达的距离不超过d时,该小岛可以被雷达覆盖。
我们使用笛卡尔坐标系,定义海岸线为x轴,海的一侧在x轴上方,陆地一侧在x轴下方。
现在给出每个小岛的具体坐标以及雷达的检测范围,请你求出能够使所有小岛都被雷达覆盖所需的最小雷达数目。
Input
第一行输入两个整数n和d,分别代表小岛数目和雷达检测范围。
接下来n行,每行输入两个整数,分别代表小岛的x,y轴坐标。
同一行数据之间用空格隔开。
Output
- 输出一个整数,代表所需的最小雷达数目,若没有解决方案则所需数目输出“-1”。
Data Size
- 1≤n≤1000
Sample Input
3 2 1 2 -3 1 2 1
Sample Output
2
题解:
- 贪心。
- 对于每个小岛,可以求出能控制它的区间(勾股定理)。这样,问题就转换为了n个区间,每个区间内至少要有一个点,求最小点的数量。
- 这不就是裸奔的贪心模型吗?先将区间按右端点从小到大排序,然后遍历每个区间。如果最后一个取的点在当前区间内,就不做处理。否则,最后一个取的点变为当前区间的右端点,ans++。最后ans即为所求。
- 证明很简单,假设当前有两个区间,已经按右端点排好了序,那么就有以下几种情况:
第一个情况:如图,肯定取第一区间的右端点最优
|———|
......|———|
第二个情况:如图,还是取第一区间的右端点最优
...|———-|
|—————–|
第三个情况:如图,只能将最后一个取的点变为第二区间的右端点,然后ans++
|———-|
..............................|———–|
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#define N 1005
using namespace std;
struct A {double l, r;} a[N];
int n, ans;
double d, last = -1000000007;
bool cmp(A x, A y) {return x.r < y.r;}
int main()
{
cin >> n >> d;
for(int i = 1; i <= n; i++)
{
double x, y;
cin >> x >> y;
if(y > d) {cout << -1; return 0;}
double k = sqrt(d * d - y * y);
a[i].l = x - k, a[i].r = x + k;
}
sort(a + 1, a + 1 + n, cmp);
for(int i = 1; i <= n; i++)
if(last < a[i].l) last = a[i].r, ans++;
cout << ans;
return 0;
}