洛谷P17331题解

分析

题意

给定一个长度为 nn 的数组,每次操作可以选择一个数 aia_i 和一个整数 xx0x<ai0 \le x < a_i),花费 xx 的代价将 aia_i 变成 aixa_i-x。求使数组 mex\operatorname{mex}kk 的最小总代价,无法实现则输出 1-1

思路

  1. 为了使 MEX 为 kk,则需构造出 1k11 \sim k-1 且消除 kk。将数组排序后,用最小的可用数去匹配目标 tt(从 11k1k-1)。
  2. 遍历数组,若 aita_i \ge t,将其减为 tt,代价加 aita_i-ttt11。若遍历结束 t<kt < k,则无解。
  3. 最后遍历剩余元素,若有等于 kk 的数,需额外花费 11 的代价将其减小。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
typedef long long ll;
ll a[N];
int main() {
int T;
cin >> T;
while (T--) {
int n, k;
cin >> n >> k;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n);
if (k == 1) {
if (n > 0 && a[0] == 1) cout << -1 << endl;
else cout << 0 << endl;
continue;
}
ll ans = 0;
int t = 1, idx = 0;
while (idx < n && t < k) {
if (a[idx] >= t) {
ans += a[idx] - t;
t++;
}
idx++;
}
if (t != k) {
cout << -1 << endl;
continue;
}
while (idx < n) {
if (a[idx] == k) ans++;
idx++;
}
cout << ans << endl;
}
return 0;
}

洛谷P17331题解
https://lijingshu2014.github.io/2026/08/29/洛谷P17331题解/
作者
lijingshu
发布于
2026年8月29日
许可协议