Saruman's Army--POJ3069

[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;
}
发布了63 篇原创文章 · 获赞 8 · 访问量 7199

猜你喜欢

转载自blog.csdn.net/s1547156325/article/details/104329766