1. 程式人生 > 實用技巧 >Codeforces 1375D Replace by MEX(思維題)

Codeforces 1375D Replace by MEX(思維題)

題意:給出一個長度為n的陣列,0<=a【i】<=n,每一次操作可以把任意一個a【i】換成mex,求多少次操作使得陣列a為非遞減序列,輸出操作次數和操作的i,任意一種滿足情況的即可。n<1e3

題解:嘗試直接構造0,1,2---n-1這樣的序列,分兩種情況,mex!=n的時候把mex交換到a【mex】=mex;當mex=n時,找一個不滿足a【i】=i的位置替換即可,不然會死迴圈。

#include <bits/stdc++.h>
#define IO_read ios::sync_with_stdio(false);cin.tie(0)
#define fre freopen("C:\\in.txt", "r", stdin)
#define
_for(i,a,b) for(int i=a; i< b; i++) #define _rep(i,a,b) for(int i=a; i<=b; i++) #define inf 0x3f3f3f3f #define lowbit(a) ((a)&-(a)) using namespace std; typedef long long ll; template <class T> void read(T &x) { char c; bool op=0; while(c=getchar(), c<'0'||c>'9') if(c=='
-') op=1; x=c-'0'; while(c=getchar(), c>='0'&&c<='9') x=x*10+c-'0'; if(op) x=-x; } const int maxn=1e3+5; int T, n, a[maxn]; int k, vis[maxn]; vector<int> vec; int mex() { _for(i, 0, n) if(!vis[i]) return i; return n; } int find_pos() { _for(i, 0, n) if(a[i]!=i) return
i; return -1; } int main() { //fre; read(T); while(T--) { read(n); memset(vis, 0, sizeof(vis)); k=0, vec.clear(); _for(i, 0, n) read(a[i]), vis[a[i]]++; while(true) //for(int i=1; i<=2*n; i++) { int p=find_pos(); if(p==-1) break; int x=mex(); if(x==n){ vis[a[p]]--, a[p]=x, vis[a[p]]++; k++, vec.push_back(p); } else{ vis[a[x]]--, a[x]=x, vis[a[x]]++; k++, vec.push_back(x); } } printf("%d\n", k); for(auto &v: vec) printf("%d ", v+1); printf("\n\n"); } return 0; }