P1325 雷达安装
P1325 雷达安装
题目
假设海岸线是一条无限延伸的直线。它的一侧是陆地,另一侧是海洋。每一座小岛是在海面上的一个点。雷达必须安装在陆地上(包括海岸线),并且每个雷达都有相同的扫描范围
数据使用笛卡尔坐标系,定义海岸线为
输入
第一行包括
接下来
输出
一个整数表示最少需要的雷达数目,若不可能覆盖所有岛屿,输出 -1
。
样例
输入
3 2
1 2
-3 1
2 1
输出
2
提示
样例 1 解释
数据范围
对于全部数据,
思路
在解决本题之前,先分析一下区间选点问题:
数轴上有
- 比较容易想到:如果有一大一小区间,由于小区间被满足时大区间一定也被满足,所以在区间包含的情况下,大区间不需要考虑。(如上图。)
-
上述两种情况同时可以引发思考,如何对区间进行排序?假设按照区间右端点进行排序。如上图,则应该选择区间
的右端点 作为基准值(尽量更右),一旦区间 的左端点 大于 时,则说明增加一个点覆盖 ,且更新基准值为 供后面的区间进行比较。如果区间 的左端点 小于等于 ,则不需要增加新的点覆盖,基准值依然为 。 -
当进行右端点排序时,如果右端点相同,那么该如何选点?为保持相同的规律,依然选择上一个区间的右端点,左端点可任意排序。
接下来回归本题,通过分析发现该题目本质上是一个区间点覆盖问题,采用贪心策略,题目中说雷达必须安装到陆地上(包括海岸线),可以很容易地想到,对于每个不在海岸线上的雷达
由勾股定理
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1000006;
int n, ans = 1, nx;
double d;
struct Range
{
double a, b;
Range()
{
}
Range(double x, double y)
{
a = x;
b = y;
}
} r[N];
bool cmp(Range x, Range y)
{
if (x.b < y.b)
return 1;
else if (x.b == y.b && x.a > y.a)
return 1;
return 0;
}
int main()
{
scanf("%d %lf", &n, &d);
double a, b;
for (int i = 1; i <= n; i ++ )
{
scanf("%lf %lf", &a, &b);
if (b <= d)
r[i] = Range(a - sqrt(d * d - b * b), a + sqrt(d * d - b * b));
// 转换成区间问题
else
{
printf("-1");
return 0;
}
}
sort(r + 1, r + 1 + n, cmp);
nx = r[1].b;
for (int i = 2; i <= n; i ++ )
{
if (r[i].a > nx)
{
ans ++;
nx = r[i].b;
}
}
printf("%d", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】