zoukankan      html  css  js  c++  java
  • [Codeforces 864D]Make a Permutation!

    Description

    Ivan has an array consisting of n elements. Each of the elements is an integer from 1 to n.

    Recently Ivan learned about permutations and their lexicographical order. Now he wants to change (replace) minimum number of elements in his array in such a way that his array becomes a permutation (i.e. each of the integers from 1 to n was encountered in his array exactly once). If there are multiple ways to do it he wants to find the lexicographically minimal permutation among them.

    Thus minimizing the number of changes has the first priority, lexicographical minimizing has the second priority.

    In order to determine which of the two permutations is lexicographically smaller, we compare their first elements. If they are equal — compare the second, and so on. If we have two permutations x and y, then x is lexicographically smaller if xi < yi, where i is the first index in which the permutations x and y differ.

    Determine the array Ivan will obtain after performing all the changes.

    Input

    The first line contains an single integer n (2 ≤ n ≤ 200 000) — the number of elements in Ivan's array.

    The second line contains a sequence of integers a1, a2, ..., an (1 ≤ ai ≤ n) — the description of Ivan's array.

    Output

    In the first line print q — the minimum number of elements that need to be changed in Ivan's array in order to make his array a permutation. In the second line, print the lexicographically minimal permutation which can be obtained from array with q changes.

    Sample Input

    4
    3 2 2 3

    Sample Output

    2
    1 2 4 3

    HINT

    In the first example Ivan needs to replace number three in position 1 with number one, and number two in position 3 with number four. Then he will get a permutation [1, 2, 4, 3] with only two changed numbers — this permutation is lexicographically minimal among all suitable.

    题解

    又掉进了题意的坑里...

    一开始以为更换数字的代价是前后数字的差值...结果发现更换代价就是$1$...水得不能再水...

    那显然最小代价就是把多余的数字变成没有的数字。

    对于序列的字典序,也很简单,我们玩一个小贪心,显然数字越小要放越前面。我们将没有的数字从大到小压入栈中。

    从$1$~$n$遍历序列,若扫到重复的元素,如果栈顶元素比它小,显然要替换。若比它大,我们选择跳过(虽然只能跳过一次,但先跳总比后跳好),记录一下,防止之后重复跳两次。

     1 //It is made by Awson on 2017.9.29
     2 #include <set>
     3 #include <map>
     4 #include <cmath>
     5 #include <ctime>
     6 #include <queue>
     7 #include <stack>
     8 #include <vector>
     9 #include <cstdio>
    10 #include <string>
    11 #include <cstring>
    12 #include <cstdlib>
    13 #include <iostream>
    14 #include <algorithm>
    15 #define LL long long
    16 #define Max(a, b) ((a) > (b) ? (a) : (b))
    17 #define Min(a, b) ((a) < (b) ? (a) : (b))
    18 #define sqr(x) ((x)*(x))
    19 #define lowbit(x) ((x)&(-(x)))
    20 using namespace std;
    21 const int N = 200000;
    22 void read(int &x) {
    23     char ch; bool flag = 0;
    24     for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    25     for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    26     x *= 1-2*flag;
    27 }
    28 
    29 int n, a[N+5], cnt[N+5];
    30 bool skip[N+5];
    31 stack<int>S;
    32 
    33 void work() {
    34     read(n);
    35     for (int i = 1; i <= n; i++) {
    36         read(a[i]);
    37         cnt[a[i]]++;
    38     }
    39     for (int i = n; i >= 1; i--)
    40         if (!cnt[i]) S.push(i);
    41     printf("%d
    ", S.size());
    42     for (int i = 1; i <= n; i++) {
    43         if (cnt[a[i]] > 1) {
    44             if (skip[a[i]] || a[i] > S.top()) {
    45                 cnt[a[i]]--;
    46                 a[i] = S.top();
    47                 S.pop();
    48             }
    49             else skip[a[i]] = 1;
    50         }
    51     }
    52     for (int i = 1; i <= n; i++) printf("%d ", a[i]);
    53 }
    54 int main() {
    55     work();
    56     return 0;
    57 }
  • 相关阅读:
    EasyUi TreeGrid封装
    Ionic项目中使用极光推送
    Win7搭建NodeJs开发环境
    NET 平台下的插件化开发内核
    访问数据库时如何解决并发问题
    async & await 的前世今生
    Linux环境编程相关的文章
    C# 5.0 Async函数的提示和技巧
    python算法题
    如何从数组中随机取出多个不重复的项
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7610570.html
Copyright © 2011-2022 走看看