题意: 输入n个数字,半径r,每个数字可以上一个标记,影响的范围是[x-r,x+r],问最少需要多少次标记,才可以让所有点都被影响。
思路: 先对过程模拟一遍,首先先去找数组里最小的那个数a,在a+r的范围内取找尽可能接近a+r的数组里的数t,然后标记一次,ans++。下一次就从t+r+1的位置循环上面的操作,最后输出ans即可
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=5000;
int a[maxn];
bool vis[maxn];
int ans=0;
int main(void)
{
int r,n;
while(cin >> r >> n)
{
memset(vis,false,sizeof(vis));
ans=0;
if(r==-1 && n==-1)
break;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]); // 有一个细节是a这个数组对这道题没什么实质的作用。下面vis[a[i]]中,vis套了一个a[i],在数据小的情况下影响不大,当数据大的时候影响就会比较大。
vis[a[i]]=true;
}
int i,j;
for(i=0; i<=1000;i++)
{
if(vis[i]==true)
{
int t=-1;
for(j=i+1; j<=i+r; j++)
{
if(vis[j]==true)
t=j;
}
if(t!=-1) i=t+r;// 不加1的原因是for本身有i++了.
else if(t==-1) i+=r;
ans++;
}
}
cout << ans << endl;
}
return 0;
}