[C++]Saruman’s Army
Saruman’s Army:
直线上有N个点,点i的位置是Xi。从这N个点中选择若干个,给它们加上标记。对每一个点,其距离为R以内的区域里必须有带有标记的点(自己本身带有标记的点,可以认为其与距离为0的地方有一个带有标记的点)。在满足这个条件的情况下,希望能为尽可能少的点添加标记。请问至少要有多少点被加上标记?
输入格式:
The input test file will contain multiple cases. Each test case begins with a single line containing an integer R, the maximum effective range of all palantirs (where 0 ≤ R ≤ 1000), and an integer n, the number of troops in Saruman’s army (where 1 ≤ n ≤ 1000). The next line contains n integers, indicating the positions x1, …, xn of each troop (where 0 ≤ xi ≤ 1000). The end-of-file is marked by a test case with R = n = −1.
输出格式:
For each test case, print a single integer indicating the minimum number of palantirs needed.
输入:
0 3
10 20 20
10 7
70 30 1 7 15 20 50
-1 -1
输出:
2
4
解题思路:一个点的左右两边距离r以内的点都会被覆盖,从最左边的点看起(最左边的点只需要管右边有没有点覆盖它),找到与最左边的点距离r以内的最远的点。对该点加上标记,再找到对该标记点右边距离r以内的最远的点的下一个点,然后采用同样的方法找到下一个标记点,如此重复操作
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 10000;
int n;
int r;
int x[maxn];
int main(){
while(cin>>r>>n){
if(r == -1 && n == -1)
break;
for(int i = 0; i<n; i++){
cin>>x[i];
}
sort(x, x+n);
int ans = 0;
int i = 0;
while(i < n){
int res = x[i++];
while(i < n && x[i] <= res+r) i++;
int p = x[i-1];
ans++;
while(i < n && x[i] <= p+r) i++;
}
cout<<ans<<endl;
}
return 0;
}