您的位置:首页 > 其它

Codeforces Round #436 (Div. 2)-贪心-D. Make a Permutation!

2017-09-26 21:58 465 查看
http://codeforces.com/contest/864/problem/D

给定一个数列,有重复的数字,问你改变最少多少数字,能够让其成为1-m的全排列,并且字典序尽可能的小,

贪心。

标记出现多次的数的位置。

如果当前要插入的值小于 当前的位置。

那么就换。

否则,如果前面已经出现过了,那么也换。

不然就换下一个。

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
/*  用一个优先队列,
当当前最小的值 小于他。
或者 他前面出现了,都这样搞。
*/
const int maxn=2e5+1000;
int num[maxn];
queue<int>q;
bool vis[maxn];
int a[maxn];
int m;
int main() {
while(~scanf("%d",&m)){
memset(num,0,sizeof(num));
while(!q.empty()) q.pop();
memset(vis,false,sizeof(vis));
for(int i=1;i<=m;i++){
scanf("%d",&a[i]);
num[a[i]]++;
}
int ans=0;
for(int i=1;i<=m;i++){
if(!num[i]){
q.push(i),ans++;
//cout<<i<<endl;
}
}
for(int i=1;i<=m;i++){
if(num[a[i]]>=2){
int s;
//if(!q.empty())
s=q.front();
//cout<<s<<"**"<<endl;
if(vis[a[i]]||s<a[i]){
q.pop();
num[a[i]]--;
a[i]=s;
//vis[a[i]]
}
else{
vis[a[i]]=true;
}
}
}
printf("%d\n",ans);
for(int i=1;i<=m;i++){
if(i==1)
printf("%d",a[i]);
else
printf(" %d",a[i]);
}
cout<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: