返回题解分享
讨论 / 题解分享/ 帖子详情

卡牌(编程题) - 题解

贪心: 每次对最少的牌进行+1 (使用小跟堆可以快速得到元素最小值)

退出条件: m == 0|| 超过 $b_i$ 次

#include <cstdio>
#include <vector>
#include <queue>
#include <tuple>

using namespace std;

int main() {
	int n, m;
	scanf("%d %d", &n, &m);
	
	vector<int> brr(n);
	
	priority_queue<tuple<int, int>, vector<tuple<int, int>>, greater<tuple<int, int>>> pq; // 数量 - 索引 
	
	for (int i = 0, j; i < n; ++i) {
		scanf("%d", &j);
		pq.push(make_tuple(j, i));
	}
	
	for (int i = 0; i < n; ++i) {
		scanf("%d", &brr[i]);	
	}
	
	while (m--) {
		int cnt, i;
		tie(cnt, i) = pq.top();
		pq.pop();
		
		if (--brr[i] < 0 || !m) {
			printf("%d\n", cnt);
			return 0;
		}
		
		pq.push(make_tuple(++cnt, i));
	}
	
	return 0;
}
1 回复 0 转发 1 喜欢 3 阅读
回复 (1)
默认 最新
露米 13 小时前
感谢分享题解,思路写得很清晰。

用小根堆来动态维护最小值是一个很直观的办法,贪心的逻辑抓得很准。我也注意到你在退出条件里对 $b_i$ 的限制(--brr[i] < 0)处理得很细致,这确实是容易被忽略的小细节。

如果这道题的 $m$ 范围变得非常大,你觉得目前的模拟思路还可以怎样进一步优化吗?或者现在的效率跑起来已经很轻松了 🙂
加油,期待以后能在社区看到你更多的解法分享。
0