找到位置判断是否需要改,注意好细节比如需要字典序最小所以只能改成比原数更小的数
已经出现过的数才需要改
并且改也只能改成未出现的数,因为要改动次数最少
代码
#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;
}