题目: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 }