Saruman's Army POJ - 3069(思维贪心)

本文探讨了一种算法问题,即如何用最少的将军覆盖所有士兵的位置。通过尺取贪心策略,结合半径覆盖特性,文章详细介绍了算法的实现过程,并提供了一段C++代码示例,展示了如何通过两次遍历确定每个将军的最佳位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目的大意就是给出几队士兵,有好几堆(给出每堆士兵所在位置),现在要求出给最少的将军,将军可以管住士兵(有一个观察半径),在观察半径内的就可以满足条件(刚好在半径上也算是被管住)。

输入

观察半径r,和士兵的堆数n,(where 0 ≤ r≤ 1000)(1≤n≤1000) 

Sample Input

0 3
10 20 20
10 7
70 30 1 7 15 20 50
-1 -1

Sample Output

2
4

看样子是个尺取贪心,但是这个贪心形式是个半径(圆的东西),这个怎么写代码呢?观摩大神代码,就是先贪一半(一个半径),然后再贪另一个半径,这样就可以将这个半径范围完美地表达出来了。代码:
 

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<set>
using namespace std;
const int maxn=1000;
int a[maxn]; 
int main()
{
	int r,n,i=0,k=0;
	while(cin>>r>>n)
	{
		if(r==-1&&n==-1)
			break;
		memset(a,0,sizeof(a));
		k=0;
		for(i=0;i<n;i++)
			cin>>a[i];
		sort(a,a+n);
		i=0;
		while(i<n)
		{
			int zuozhi=a[i++];
			while(i<n&&a[i]<=zuozhi+r)
				i++;
			int p=a[i-1];
			while(i<n&&a[i]<=p+r)
				i++;
			k++;
		}
		cout<<k<<endl;
	}


	return 0;
}

两个while 一个是左边的半径(能到达的最大位置),另一个是右边半径(能到达的最大位置),最后放置将军。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值