给你一个序列,让你用最少次的改变数,来使这个序列变成1到n的排列。答案要字典序最小。输出次数和排列。
POINT:
先找出需要哪些数,然后一个一个判断。
当然是重复的数改成这些需要数,需要数从小到大排序。
重复的数如果比最小需要数小,那么就保留这一个《第一个》重复的数,后面还遇到了这个数就直接替换为最小需要数。
如果比最小需要数大,直接替换,直到不重复。
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn = 200100;
int a[maxn];
int cnt[maxn];
int kk[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
cnt[a[i]]++;
}
int num=0;
int ans[maxn];
for(int i=1;i<=n;i++){
if(cnt[i]==0){
ans[++num]=i;
}
}
// memset(kk,0,sizeof kk);
int c=1;
for(int i=1;i<=n&&c<=num;i++){
if(kk[a[i]]){
a[i]=ans[c++];
continue;
}
if(cnt[a[i]]>=2){
if(ans[c]<a[i]){
cnt[a[i]]--;
a[i]=ans[c++];
}
else
kk[a[i]]=1;
}
}
printf("%d\n",num);
for(int i=1;i<=n;i++){
if(i-1) printf(" ");
printf("%d",a[i]);
}
printf("\n");
}