112. 雷达设备
题解
出现的错误
- 自己一开始把题目都读错了。题目问的是最少设置多少个雷达把岛屿全部覆盖,自己想当然成一个雷达最多可以覆盖多少个岛屿。
自己思路整理:
是将二维平面问题转化为一维线段问题
分为2种情况
岛屿与x轴的距离 > d
雷达肯定搜不到这个岛屿,无解
雷达可以搜到,这时(x,y)
表示岛屿的坐标,则可以求出在x轴[a,b]
内的雷达都可以扫描到该岛屿。
具体的解法,算法是题解里的:
算法步骤:
- 将所有区间按右端点从小到大排序;
- 依次考虑每个区间:
- 如果当前区间包含最后一个选择的点,则直接跳过;
- 如果当前区间不包含最后一个选择的点,则在当前区间的右端点的位置选一个新的点
思考
因为每一段区间代表了一个岛屿,所以是在每段区间的最右边建雷达(贪心的思想,越往右后面能顾及的岛屿越多),然后看下一个岛屿,下一个岛屿也是一段区间,如果这段区间最左边和上一段区间最右边有交集,也就是
则雷达一定能覆盖到当前红色的点。
当覆盖不到时,说明需要再加一个雷达,加到当前覆盖不到的区间的最右侧。
最后的结果肯定是找到了x个没有交集的区间,雷达就建在每个区间的最右侧。
所以这个地方需要一个last存储最后一个点在哪里。意为最后一个雷达放置的位置
注意last要设置为double!
常人皆犯错
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1010;
int n,d;
struct Segment
{
double l,r;
bool operator<(const struct Segment x) const{
return r < x.r;
}
}a[N];
int main()
{
cin>>n>>d;
for(int i=1;i<=n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(y > d)
{
puts("-1");
return 0;
}
double c = sqrt(d*d - y*y);
a[i].l = x - c;
a[i].r = x + c;
}
sort(a+1,a+1+n);
double last = -0x3f3f3f3f;
int sum = 0;
for(int i=1;i<=n;i++)
{
if(a[i].l <= last) continue;
else
{
last = a[i].r;
sum++;
}
}
printf("%d",sum);
}