

POJ 1328 - Radar Installation
source link: https://exp-blog.com/algorithm/poj/poj1328-radar-installation/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Radar Installation
转化问题,使用贪心算法求解。
/*
Author: Exp
Date: 2017-12-06
Code: POJ 1328
Problem: Radar Installation
URL: http://poj.org/problem?id=1328
*/
/*
题意分析:
给定一个直角坐标系,定义x轴为海岸线,海岸线上方是海,下方是陆地.
在海域零星分布一些海岛, 需要要在海岸线上安装若干个雷达覆盖这些海岛,
每个雷达的覆盖半径都是相同且固定的.
现在给定所有海岛的坐标(x,y), 以及雷达的覆盖半径d,
问可以覆盖所有海岛的最小雷达数.
解题思路:
首先可以明确的是:只要存在任意一个海岛位置超出雷达最大覆盖半径(即y>d),则无解.
在所有海岛的 y<=d 的前提下去思考此问题,
那么此问题的切入点是需要知道【一个雷达要覆盖一个海岛,其可以安装范围是多少】
以海岛坐标(x,y)为圆心,用雷达覆盖半径d画圆,根据前提条件可知,
这个圆与x轴必定存在最少1个(y=d)、最多2个交点(y<d).
可以认为1个交点是2个交点重合的特殊情况,那么这2个交点在x轴上构成的线性区间,
可以看作海岛的被覆盖范围在x轴上的投影 (由此就可以把二维的几何问题转化成一维几何问题)
按照所有海岛的x轴坐标,从小到大依次计算每个海岛在x轴上的投影区间(投影可能存在重叠),
同时把每个雷达抽象成1个点,那么此问题就转化成:
【已知x轴上若干个区间(可能存在交集),现在要往这些区间内放若干个点,
问怎样放置这些点,使得每个区间内至少存在一个点,且所放置的点的总量尽可能最少】
可使用贪心算法求解:
根据每个区间的左端点坐标对所有区间从左到右排序:
① 在左起第一个区间A 的右端点 A.R 放置一个点,总放置点数 P+1
② 若下一个区间B 的左端点 B.L > A.R,
说明 区间A 与 区间B 无交集,此时在区间B 的右端点 B.R 放置一个点,总放置点数 P+1
否则说明 区间A 与 区间B 相交, 此时进一步判断,若 B.R < A.R,
说明 区间B 在 区间A 的内部,此时把原本放置在 A.R 的点移动到 B.R(确保区间B有一个点),总放置点数不变
③ 重复这个过程直到所有区间被遍历完成
*/
#include <math.h>
#include <algorithm>
#include <iostream>
using namespace std;
// 海岛在x轴上的投影区间
struct Interval {
double left; // 左端点在x轴上的坐标
double right; // 右端点在x轴上的坐标
};
/*
* 求解问题:在每个区间内至少放置一个点,使得放置的点的总量最少
* @param intervals 区间集合
* @param size 区间个数
* return 最小的放置点数
*/
int solve(Interval* intervals, int size);
/*
* 比较两个区间的大小(用于排序)
* 左端点越小的区间,该区间的顺次越小
* @param a 区间a
* @param b 区间b
* return a.left <= b.left
*/
bool compare(Interval a, Interval b);
int main(void) {
int island, radius, testCase = 0;
while((cin >> island >> radius) && island && radius) {
const double R2 = radius * radius; // 半径平方
Interval* intervals = new Interval[island];
bool isSolvable = true;
for(int i = 0; i < island; i++) {
double x, y;
cin >> x >> y;
if(y > radius) { // 存在海岛不在雷达的最大影响范围,无解
isSolvable = false;
}
double offset = sqrt(R2 - y * y); // 勾股定理
intervals[i].left = x - offset;
intervals[i].right = x + offset;
}
int minRadar = (isSolvable ? solve(intervals, island) : -1);
cout << "Case " << ++testCase << ": " << minRadar << endl;
delete[] intervals;
}
return 0;
}
int solve(Interval* intervals, int size) {
sort(intervals, intervals + size, compare);
int minPoint = 1;
double right = intervals[0].right;
for(int i = 1; i < size; i++) {
// 区间i-1 与 区间i 无交集
if(intervals[i].left > right) {
minPoint++;
right = intervals[i].right;
// 区间i-1 在 区间i 内部
} else if(intervals[i].right < right) {
right = intervals[i].right;
} else {
// Undo: 区间i-1 与 区间i 相交
}
}
return minPoint;
}
bool compare(Interval a, Interval b) {
return a.left <= b.left;
}
Recommend
-
16
POJ 3071 Football 2020年9月24日2020年12月16日 by woshiluo 1 题目大意 给定 2n 个整数,从 1 到 2n 编号 给定 pi,...
-
4
Armin's BlogPOJ 1611 The Suspects(并查集)November 28, 2015题目链接 题意:非典时期,共有 n 个人(标号 0~n-1),分成 m 组。第一行输入 n(0...
-
13
Armin's BlogPOJ 2524 Ubiquitous Religions(并查集)November 29, 2015题目链接 题意:调查学校的学生宗教信仰情况,第一行输入 n(总人数)和 m,...
-
10
poj 1455 Crazy tea party 2013-10-03 分类:ACM 阅读(4401) 评论(0) 这道题第一眼看去很难,其...
-
19
poj 1503 高精度加法 2013-09-07 分类:未分类 阅读(4401) 评论(0) 把输入...
-
9
poj 1205 :Water Treatment Plants (DP+高精度) 题意:有n个城市,它们由一个污水处理系统连接着,每个城市可以选择1、将左边城市过来的污水和右边城市过来的污水连同本身的污水排到河里 >V<2、将左边来的污水连同自己的污水排...
-
15
poj 2155 Matrix (二维树状数组) 2013-08-31 分类:未分类 阅读(4293) 评论(0) ...
-
7
poj 1990 MooFest 树状数组 2013-08-24 分类:未分类 阅读(4320) 评论(0) ...
-
1
poj.org is broken? poj.org is broken?
-
5
October 4, 2022 ...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK