Codeforces Round #436 D. Make a Permutation!
题意:给你n个数字,其中可能有相同的数字,要求你用其他的数字替换这些相同的数字,使得所得的序列字典序最小。
Examples
Input
4
3 2 2 3
Output
2
1 2 4 3
Input
6
4 5 6 3 2 1
Output
0
4 5 6 3 2 1
Input
10
6 8 4 6 7 1 6 3 4 5
Output
3
2 8 4 6 7 1 9 3 10 5
思路:暴力就好,那数组记录一下,注意:替换的时候要用比他小的换,如果选择了一个不换,那么后面的数就必须要换掉了。
代码:
#include<iostream>
#include<string.h>
using namespace std;
const int maxn=2e5+5;
int num[maxn],a[maxn];
bool f[maxn];
//f标记数组,标记有没有出现没有换的情况
int main(){
int n;
cin>>n;
memset(num,0,sizeof(num));
memset(f,0,sizeof(f));
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
cin>>a[i];
num[a[i]]++; //num记录每个数出现了几次
}
int cur=1,sum=0; //cur表示用来替换的数
for(int i=0;i<n;i++){
if(num[a[i]]>1){
while(num[cur])cur++; //要找一个没有出现的数来换
if(cur<a[i]||f[a[i]]==1){ //如果cur小于当前的数就换;或者之前有一个没有换,那么之后的都必须换了
num[a[i]]--;
a[i]=cur;
num[cur]=1;
sum++;
}
else f[a[i]]=1; //如果cur大于当前这个数,可以选择不换,就标记一下。
}
}
cout<<sum<<endl;
for(int i=0;i<n;i++){
if(i!=0)cout<<' ';
cout<<a[i];
}
return 0;
}