今天开始恢复训练(其实省赛完了玩了好久),发现了这道一年前做过的题,神特么没写出来QAQ。
我想的是选择覆盖的点越多越好的点,然后拼命写每个点覆盖了多少个点然后贪心...就是没稍微转一下,覆盖的最多那不就是越远越好么(在r的范围内)...所以这个题:从第一个没处理的点开始向右找最远的,能覆盖的点,设为s,那么这个s点就是第一个标记点,然后从s开始向右找最远的能覆盖的点,那么这个点就是第一个覆盖区间里最后一个点。依次操作即可。
我写的三层循环但是实际上复杂度还是O(N)。
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=1e3+10;
int rr,n;
int arr[maxn],vis[maxn];
int main()
{
while(scanf("%d%d",&rr,&n) && rr!=-1 && n!=-1)
{
memset(vis,-1,sizeof(vis));
for(int i=1; i<=n; i++)
scanf("%d",&arr[i]);
sort(arr+1,arr+1+n);
int ans=1;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
if(arr[i]+rr<arr[j])
{
for(int k=j;k<=n;k++)
{
if(arr[j-1]+rr<arr[k])
{
ans++;
i=k-1;
break;
}
}
break;
}
}
}
printf("%d\n",ans);
}
return 0;
}