找到位置判断是否需要改,注意好细节比如需要字典序最小所以只能改成比原数更小的数
已经出现过的数才需要改
并且改也只能改成未出现的数,因为要改动次数最少
代码
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int num[200005]; int vis[200005]; int has[200005]; int main() { int N;; while(~scanf("%d",&N)) { memset(vis,0,sizeof vis); memset(has,0,sizeof has); int cnum=1; int cnt=0; for(int i=0;i<N;i++) { scanf("%d",&num[i]); vis[num[i]]++; } for(int i=0;i<N;i++) { if(vis[num[i]]>1) { while(vis[cnum]) cnum++; if(cnum>=num[i]&&!has[num[i]]) { has[num[i]]++; continue; } cnt++; vis[num[i]]--; vis[cnum]++; num[i]=cnum; } } printf("%d\n%d",cnt,num[0]); for(int i=1;i<N;i++) printf(" %d",num[i]); printf("\n"); } return 0; }