Codeforces-1375-D-Replace by MEX
阿新 • • 發佈:2020-07-08
題意:
有一個長度為 n 的陣列 a, \(0 \le a_i \le n\) .
一次操作可以選擇陣列中的任何元素,並將其替換為陣列元素的MEX ( MEX是陣列中未出現的最小自然數 ) .
請找到一個能讓陣列非遞減的解決方案(保證運算元 2n 之內必有解決方案)。
思路:
保證運算元 2n 之內讓陣列最終變為 \([0,1,…,n−1]\) .(\(s[i] = i\))
每一次操作:遍歷陣列,找到MEX。
如果 MEX < n ,就將它放到最終的位置上,即 s[MEX]。
如果 MEX = n,就遍歷陣列,找一個沒有歸位的位置,即 \(s[i] != i\) 的位置。
這樣可以保證至多兩個操作,就可以使一個數字歸位。總運算元小於等於 2n。
AC程式碼:
#include<bits/stdc++.h> using namespace std; int s[1003]; int getMex(int n) { vector<int> a(n + 1, 0); for (int i = 0; i < n; ++i) a[s[i]] = 1; for (int i = 0; i <= n; ++i) if (a[i] == 0) return i; } int check(int n) { for (int i = 0; i < n; ++i) if (s[i] != i) return i; return -1; } inline void solve() { vector<int> ans; int n; cin >> n; for (int i = 0; i < n; ++i) cin >> s[i]; while (check(n) != -1) { int mex = getMex(n), pos = mex; if (mex == n) pos = check(n); s[pos] = mex; ans.push_back(pos); } cout << ans.size() << endl; for (auto i : ans) cout << i + 1 << " "; cout << endl; } int main() { int T = 1; cin >> T; for (int i = 1; i <= T; ++i) solve(); return 0; }