POJ3069 题解

334 阅读1分钟

题目链接

思路

首先排序。利用贪心的思路,每一个点都必须要被覆盖,尽量选择靠后的位置进行标记,这样才能在标记到前面所有点的同时尽可能多地覆盖后面的点。记现在第一个需要标记的点为tar,当找到第一个无法覆盖tar的点时,就标记该点前面的点,并维护一个cur,表示标记过的点覆盖能覆盖到哪里。

代码

#include <iostream>
#include <algorithm>
#define rep(i,st,ed) for(int i=st;i<=ed;++i)
using namespace std;
const int N=1E3+10;
int r,n,ans;
int a[N];
void solve()
{
	cin>>r>>n;
	if(r==n && n==-1)
		exit(0);
	rep(i,1,n)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	int tar=a[1],cur=-1;
	rep(i,1,n)
	{
		int ltar=a[i]-r;
		if(ltar>tar)	//this node can't cover the last node
		{
			cur=a[i-1]+r;
			for(;i<=n;++i)
			{
				if(a[i]>cur)
				{
					tar=a[i];
					break;
				}
			}
			++ans;
		}
	}
	if(a[n]>cur)
		++ans;
	cout<<ans<<endl;
	ans=0;
}
int main()
{
	while(1)
		solve();
}