POJ 3069 Saruman's Army 题解 《挑战程序设计竞赛》

题目:POJ - 3069 

书中例题,关键解法(区间去重)很典型,因此记下来。

我们从最左边开始考虑。对于这个点,到距其R以内的区域内必须要有带有标记的点。(此点位于最左边,所以显然)带有标记的这个点一定在此点右侧(包含这个点自身)。

于是,究竟要给哪个点加上标记呢?答案应该是从最左边的点开始,距离为R以内的最远的点,因为更左的区域没有覆盖的意义,所以应该尽可能覆盖更靠右的点。

如上所示(图),加上了第一个标记后,剩下的部分也用同样的办法处理。对于添加了符号的点右侧相距超过R的下一个点,采用同样的方法找到其右侧R距离以内最远的点添加标记。在所有的点都被覆盖之前不断重复这一过程。

 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 int r;
 7 int n;
 8 int x[1000];
 9 
10 void solve() {
11     int res = 0;
12     sort(x, x + n);
13     
14     int i = 0;
15     while (i < n) {
16         int s = x[i++];
17         while (i < n && x[i] <= s + r) {
18             i++;
19         }
20         int p = x[i - 1];
21         while (i < n && x[i] <= p + r) {
22             i++;
23         }
24         res++;        
25     }
26     cout << res << endl;
27 }
28 
29 int main() {
30     while (cin >> r >> n && r != -1) {
31         for (int i = 0; i < n; i++) {
32             cin >> x[i];
33         }
34         
35         solve();
36     }
37     return 0;
38 }
原文地址:https://www.cnblogs.com/carolunar/p/6378342.html