2024.12.30 周一
2024.12.30 周一
Q1. 1100
Farmer John has a permutation \(p_1, p_2, \ldots, p_n\), where every integer from \(0\) to \(n-1\) occurs exactly once. He gives Bessie an array \(a\) of length \(n\) and challenges her to construct \(p\) based on \(a\).
The array \(a\) is constructed so that \(a_i\) = \(\texttt{MEX}(p_1, p_2, \ldots, p_i) - p_i\), where the \(\texttt{MEX}\) of an array is the minimum non-negative integer that does not appear in that array. For example, \(\texttt{MEX}(1, 2, 3) = 0\) and \(\texttt{MEX}(3, 1, 0) = 2\).
Help Bessie construct any valid permutation \(p\) that satisfies \(a\). The input is given in such a way that at least one valid \(p\) exists. If there are multiple possible \(p\), it is enough to print one of them.
Input
It is guaranteed that there is at least one valid \(p\) for the given data.
------------------------独自思考分割线------------------------
-
MEX函数的三种思考方向:加数会变/不变,反向考虑去数能够 \(O(1)\) 找到值。
A1.
- 对MEX函数向集合加数只需要考虑2个方向:MEX变/不变。一种方案是先考虑不变,不合法再考虑变。
- 第一次写这道题是在12.11,一直T16,当时是先考虑变,这样的话找更新值的时候会T。
- 这样做是过了,但是很难证明是对的。
- 正解时从后向前构造,这样有制约关系,就一定是对的。
------------------------代码分割线------------------------
A1.
#include <bits/stdc++.h>
#define int long long //
#define endl '\n' // 交互/调试 关
using namespace std;
#define bug(BUG) cout << "bug:# " << (BUG) << endl
#define bug2(BUG1, BUG2) cout << "bug:# " << (BUG1) << " " << (BUG2) << endl
#define bug3(BUG1, BUG2, BUG3) cout << "bug:# " << (BUG1) << ' ' << (BUG2) << ' ' << (BUG3) << endl
void _();
signed main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cout << fixed << setprecision(6);
int T = 1;
cin >> T;
while (T--)
_();
return 0;
}
void _()
{
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++)
cin >> a[i];
vector<int> st(n + 1);
int mex = 0;
auto find = [&]()
{
while (st[mex])
mex++;
};
for (int i = 1; i <= n; i++)
{
int p = mex - a[i];
if (p >= 0 && p < n && !st[p])
st[p] = 1;
else
{
p = mex;
st[p] = 1;
find();
}
// bug2(i, mex);
cout << p << ' ';
}
cout << endl;
}

浙公网安备 33010602011771号