P16816 [蓝桥杯 2026 国 Python B] 贴纸册交换 题解

C++ 题解。

题目传送门

题意

有 \(N\) 种贴纸,编号 \(1\) 到 \(N\)。按顺序得到 \(M\) 张贴纸,第 \(i\) 张编号为 \(A_i\)。

  • 如果没收集过 \(A_i\),就贴上。
  • 如果收集过 \(A_i\),就变成 \(1\) 张交换券。
  • 如果凑够 \(K\) 张券,立刻换当前编号最小且没收集的贴纸。

问最后收集了多少种。

思路

直接模拟即可。

用 \(sum\) 记录已收集种类数,\(s\) 记录当前券数。

如果每次兑换都从 \(1\) 开始找最小缺失会 超时,可以用一个指针 \(p\) 记录当前可能的最小缺失编号。

代码

#include 
#define Jason227 return
#define Code 0
using namespace std;const int MAXN = 200010, MAXM = 200010;
int N, M, K, A[MAXM], s = 0, sum = 0, p = 1;
bool B[MAXN];int main(){cin >> N >> M >> K;for(int i = 1; i <= M; i++){cin >> A[i];if(B[A[i]]){s++;if(s == K){for(int j = p; j <= N; j++){if(!B[j]){s = 0, sum++, p = j;B[j] = true;break;}}}}else{B[A[i]] = true;sum++;}}cout << sum << '\n';Jason227 Code;
}

复杂度分析

  • 时间复杂度:\(O(N + M)\)。每个贴纸处理一次,指针 \(p\) 总共右移不超过 \(N\) 次。
  • 空间复杂度:\(O(N + M)\)。存贴纸数组和标记数组。

AC 记录