POJ 3069 Saruman's Army (简单贪心)

在一条路径上,萨鲁曼需部署监视器确保每个单位都在其有效范围内。此题探讨如何通过算法找到最少的监视器数量,以实现路径全覆盖。


Saruman's Army
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5343 Accepted: 2733

Description

Saruman the White must lead his army along a straight path from Isengard to Helm’s Deep. To keep track of his forces, Saruman distributes seeing stones, known as palantirs, among the troops. Each palantir has a maximum effective range of R units, and must be carried by some troop in the army (i.e., palantirs are not allowed to “free float” in mid-air). Help Saruman take control of Middle Earth by determining the minimum number of palantirs needed for Saruman to ensure that each of his minions is within R units of some palantir.

Input

The input test file will contain multiple cases. Each test case begins with a single line containing an integer R, the maximum effective range of all palantirs (where 0 ≤ R ≤ 1000), and an integer n, the number of troops in Saruman’s army (where 1 ≤ n ≤ 1000). The next line contains n integers, indicating the positions x1, …, xn of each troop (where 0 ≤ xi ≤ 1000). The end-of-file is marked by a test case with R = n = −1.

Output

For each test case, print a single integer indicating the minimum number of palantirs needed.

Sample Input

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

Sample Output

2
4

Hint

In the first test case, Saruman may place a palantir at positions 10 and 20. Here, note that a single palantir with range 0 can cover both of the troops at position 20.

In the second test case, Saruman can place palantirs at position 7 (covering troops at 1, 7, and 15), position 20 (covering positions 20 and 30), position 50, and position 70. Here, note that palantirs must be distributed among troops and are not allowed to “free float.” Thus, Saruman cannot place a palantir at position 60 to cover the troops at positions 50 and 70.

Source

Stanford Local 2006

题目链接:http://poj.org/problem?id=3069

题目大意:数轴上有些点,每个点可以放个什么鬼东西,可以覆盖R范围,问最少需要多少个这个东西

题目分析:好像是挑战那本书上的题,从左往右扫,找圆心位置即可



#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
int x[1005];

int main()
{
	int r,n;
	while(scanf("%d %d", &r, &n) != EOF && (r != -1 && n != -1))
	{
		for(int i = 0; i < n; i++)
			scanf("%d", &x[i]);
		sort(x, x + n);
		int ans = 0, i = 0;
		while(i < n)
		{
			int a1 = x[i++];
			while(i < n && x[i] <= a1 + r)
				i ++;
			int a2 = x[i - 1];
			while(i < n && x[i] <= a2 + r)
				i++;
			ans++;
		}
		printf("%d\n", ans);
	}
}



### 关于POJ 3069问题的解题思路 POJ 3069题目通常涉及图论中的最小生成树(Minimum Spanning Tree, MST)问题。该类问题的核心在于通过Kruskal算法或Prim算法来寻找连接所有节点所需的最低成本边集合。 #### Kruskal算法的应用 Kruskal算法是一种贪心策略,用于解决无向加权连通图中的MST问题。其基本原理是对所有的边按照权重从小到大排序,并依次尝试加入当前边至已有的森林中[^4]。如果加入某条边不会形成环,则将其纳入最终的MST;否则跳过这条边。此过程需借助并查集数据结构以高效检测是否存在环。 以下是基于Python实现的一个简单版本: ```python class UnionFind: def __init__(self, size): self.parent = list(range(size)) def find(self, x): if self.parent[x] != x: self.parent[x] = self.find(self.parent[x]) return self.parent[x] def union_set(self, x, y): rootX = self.find(x) rootY = self.find(y) if rootX != rootY: self.parent[rootY] = rootX def kruskal(edges, num_nodes): edges.sort(key=lambda edge: edge[2]) # Sort by weight. uf = UnionFind(num_nodes) mst_weight = 0 count_edges = 0 for u, v, w in edges: if uf.find(u) != uf.find(v): uf.union_set(u, v) mst_weight += w count_edges += 1 if count_edges == num_nodes - 1: break return mst_weight if count_edges == num_nodes - 1 else float('inf') ``` 这段代码定义了一个`UnionFind`类用来管理各个顶点所属的集合状态,并实现了Kruskal核心逻辑函数kruscal()。它接受边列表edges以及节点数量num_nodes作为参数返回总代价或者无穷大表示无法构建完整的MST[^5]。 #### Prim算法简介 另一种求解方法是采用Prim算法,在处理稠密图时可能更有效率。Prim从任意起点出发逐步扩展最短路径直到覆盖整个图为止。每次迭代都选取尚未访问过的邻接点中最轻的一条边接入现有子图之中[^6]。 虽然这里未提供具体编码实例,但理解这两种经典技术对于解答像POJ 3069这样的竞赛问题是至关重要的基础知识点之一。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值