您的位置:首页 > 其它

Codeforces 864 D Make a Permutation!

2017-10-23 13:31 483 查看
题目地址

题意:给你一个长度为n的序列,让你用最少次替换,把整个序列变成单个元素都是不重复的,然后输出字典序最小的序列

思路:通过一个标记数字去标记有多少种元素是没有出现的,把这些元素放入优先队列中(数字越小越优先),然后通过一个标记数组去标记有没有用到重复元素,如果用了一次以后就不能用了,然后如果当前数是重复元素我们就不断取出队列中最小的数于之替换(并把重复次数减一),当取出的数比他原本的大的时候,我们就看能不能用原本的数,如果可以就用并且把标记数组更新,否则就用取出的数。

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <cstdio>
#include <algorithm>
#include <iomanip>
#define N 200010
#define M 2000010//双倍
#define LL __int64
#define inf 0x3f3f3f3f
#define lson l,mid,ans<<1
#define rson mid+1,r,ans<<1|1
#define getMid (l+r)>>1
#define movel ans<<1
#define mover ans<<1|1
using namespace std;
const LL mod = 1000000007;
const double eps = 0.001;
priority_queue<int> q;
int num
, vis
;
bool flag
;
int main() {
cin.sync_with_stdio(false);
int n, cnt;
while (cin >> n) {
cnt = 0;
memset(flag, false, sizeof(flag));
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
cin >> num[i];
vis[num[i]]++;
}
for (int i = 1; i <= n; i++) {
if (vis[i] == 0) {
q.push(-i);
cnt++;
}
}
for (int i = 1; i <= n&&q.size(); i++) {
if (vis[num[i]] > 1) {
int nums = -q.top();
if (vis[num[i]] > 1) {
if (nums > num[i]) {
if (flag[num[i]]) {
vis[num[i]]--;
num[i] = nums;
q.pop();
}
else {
flag[num[i]] = true;
}
}
else {
vis[num[i]]--;
num[i] = nums;
q.pop();
}
}
}
}
cout << cnt << endl;
for (int i = 1; i <= n; i++) {
cout << num[i] << " ";
}
cout << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: