Saruman’s Army
直线上有N个点。点X的位置是Xi。从这N个点中选中若干个点,给它们添加上标记。对每一个点,其距离为R以内的区域里必须有带有标记的点(自己本身带有标记的点,可以认为与其距离为0的地方有一个带有标记的点)。在满足这个条件的情况下,希望能够为尽可能少的点添加标记?
限制条件:
1<=N<=1000
0<=R<=1000
0<=Xi<=1000
输入示例:
N=6
R=10
X={1,7,15,20,30,50}
输出示例:
3
思路:
第一步,我们可以从最左边一个点开始考虑,最左边的点的右边距离为R的区域里必须有一个被标记的点,那么我们选取哪个点呢?为了尽可能少的标记点,显然,我们选区在R内最靠右的点。
第二步,以刚才标记的点为起点,向右标记标记距离R以外的第一个点。
第三步,不断重复第二步过程……
代码如下:
//Saruman's Army
#include<iostream>
#define MAX_N 1000
using namespace std;
int N ,R ; //N表示点个数,R距离
int X[MAX_N];//X保存每个点的位置
bool point[MAX_N];
void init(){
cin>>N>>R;
for(int i=0;i<N;i++){
cin>>X[i];
}
}
void solve(){
int temp;
for(int i=1;i<N;i++){ //步骤一,找到第一个标记的点
if( (X[i]-X[0]) >=R){
point[i-1]=false;
temp=i;
break;
}
}
while(temp<N){ //循环操作步骤二
int i=temp;
i++;
if( (X[i]-X[temp]) <X[i] ){
temp=i;
point[i]=true;
}
}
int count=0; //统计标记点的个数
for(int i=0;i<N;i++){
if(point[i]) count++;
}
cout<<count<<endl;
}
int main(){
init();
solve();
return 0;
}