题目链接
题目描述
有一款著名的大型多人电子竞技游戏网站"喜爱福",网站通常会举办一些比赛。通常一名参赛选手只有一个账号,但不难猜到,总会有人"开小号"上分。
小苯就是一位该游戏的忠实玩家,他总共有 个账号,每个账号的分数分别为
。他深谙游戏中一位著名玩家 st****lk 的一句名言:"只要你永远打分更低的号,那么你的最高分就是单调不降"。
现在我们记录了小苯 次的比赛记录,已知小苯每次都会谨记 st****lk 的名言,从而使用分数最低的账号参赛。现在我们想知道小苯每次参赛后,他的最高分是多少。
输入:
- 第一行两个正整数
,分别表示小苯的账号个数和新参加的比赛记录数
- 第二行
个整数
,表示小苯每个账号目前的分数
- 第三行
个整数
,分别表示小苯每次比赛后,分数的变化值
输出:
- 输出
行,每行一个整数,表示小苯参与完第
场比赛后,他的最高分的值
解题思路
这是一个模拟问题,可以通过以下步骤解决:
-
关键发现:
- 每次都使用分数最低的账号参赛
- 需要维护所有账号的分数
- 每次比赛后需要更新最高分
-
模拟策略:
- 使用优先队列(小根堆)维护所有账号分数
- 每次从堆顶取出最小分数的账号
- 更新该账号分数后重新入堆
- 维护当前最高分
-
具体步骤:
- 初始化优先队列和最高分
- 对每场比赛:
- 取出最小分数
- 加上比赛分数变化
- 更新最高分
- 将新分数入堆
代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
priority_queue<int, vector<int>, greater<int>> pq; // 小根堆
int max_score = 0;
// 读入初始分数
for(int i = 0; i < n; i++) {
int score;
cin >> score;
pq.push(score);
max_score = max(max_score, score);
}
// 处理每场比赛
for(int i = 0; i < m; i++) {
int delta;
cin >> delta;
int min_score = pq.top(); // 取出最小分数
pq.pop();
min_score += delta; // 更新分数
pq.push(min_score);
max_score = max(max_score, min_score); // 更新最高分
cout << max_score << endl;
}
return 0;
}
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
PriorityQueue<Integer> pq = new PriorityQueue<>(); // 小根堆
int maxScore = 0;
// 读入初始分数
for(int i = 0; i < n; i++) {
int score = sc.nextInt();
pq.offer(score);
maxScore = Math.max(maxScore, score);
}
// 处理每场比赛
for(int i = 0; i < m; i++) {
int delta = sc.nextInt();
int minScore = pq.poll(); // 取出最小分数
minScore += delta; // 更新分数
pq.offer(minScore);
maxScore = Math.max(maxScore, minScore); // 更新最高分
System.out.println(maxScore);
}
}
}
import heapq
n, m = map(int, input().split())
scores = list(map(int, input().split()))
deltas = list(map(int, input().split()))
heapq.heapify(scores) # 转换为小根堆
max_score = max(scores) # 初始最高分
# 处理每场比赛
for delta in deltas:
min_score = heapq.heappop(scores) # 取出最小分数
min_score += delta # 更新分数
heapq.heappush(scores, min_score)
max_score = max(max_score, min_score) # 更新最高分
print(max_score)
算法及复杂度
- 算法:优先队列(小根堆)
- 时间复杂度:
- 每场比赛需要一次堆操作
- 空间复杂度:
- 需要存储所有账号分数