zoukankan      html  css  js  c++  java
  • 【53.57%】【codeforces 722D】Generating Sets

    time limit per test2 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    You are given a set Y of n distinct positive integers y1, y2, …, yn.

    Set X of n distinct positive integers x1, x2, …, xn is said to generate set Y if one can transform X to Y by applying some number of the following two operation to integers in X:

    Take any integer xi and multiply it by two, i.e. replace xi with 2·xi.
    Take any integer xi, multiply it by two and add one, i.e. replace xi with 2·xi + 1.
    Note that integers in X are not required to be distinct after each operation.

    Two sets of distinct integers X and Y are equal if they are equal as sets. In other words, if we write elements of the sets in the array in the increasing order, these arrays would be equal.

    Note, that any set of integers (or its permutation) generates itself.

    You are given a set Y and have to find a set X that generates Y and the maximum element of X is mininum possible.

    Input
    The first line of the input contains a single integer n (1 ≤ n ≤ 50 000) — the number of elements in Y.

    The second line contains n integers y1, …, yn (1 ≤ yi ≤ 109), that are guaranteed to be distinct.

    Output
    Print n integers — set of distinct integers that generate Y and the maximum element of which is minimum possible. If there are several such sets, print any of them.

    Examples
    input
    5
    1 2 3 4 5
    output
    4 5 2 3 1
    input
    6
    15 14 3 13 1 12
    output
    12 13 14 7 3 1
    input
    6
    9 7 13 17 5 11
    output
    4 5 2 6 3 1

    【题解】

    把一个最大的数字一直除2并不可取。
    可以想见。要让最大的数字最小。
    每次只要对最大的数字进行处理一次就好了。
    而你一直除2、除后的数字可能不是这段序列的最大值了。那样的改变是没有意义的。不会再改变整个数列的最大值。
    用优先队列维护最大值。每次对最大值进行除2。如果除1次会重复,就一直除。如果除到0了就表示不能进行操作了。则直接返回这个经过处理后的数列。
    优先队列可以直接用STL,默认最顶部为最大值。
    判断有没有重复则用map;
    以下是prioritySTL的用法

    #include <algorithm>
    #include <queue>
    
    using namespace std;
    //·····
    priority_queue<int> q;


    这样做默认为单调递增的队列。即top为最大的元素;
    如何改为单调递减的队列我下一篇文章会讲。
    一下是完整代码。

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <map>
    
    using namespace std;
    
    priority_queue <int> q;
    map <int, int> dic;
    int n;
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
        {
            int x;
            scanf("%d", &x);
            q.push(x);
            dic[x] = 1;
        }
        while (true)
        {
            int y = q.top();
            while (dic[y] && y > 0)
                y >>= 1;
            if (y == 0)
                break;
            q.pop();
            q.push(y);
            dic[y] = 1;
        }
        bool flag = false;
        while (!q.empty())
        {
            int x = q.top();
            if (!flag)
                printf("%d", x);
            else
                printf(" %d", x);
            q.pop();
            flag = true;
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    简单命令行总结
    [大餐]开发摘记1--我的Fragment通信的框架 | 卖牙膏的芖口钉
    DZNEmptyDataSet的使用
    Java笔记(一)
    mingster.com
    2014新年福利,居然有人将Ext JS 4.1的文档翻译了
    【翻译】Sencha Touch 2入门:创建一个实用的天气应用程序之三
    【翻译】在Ext JS应用程序中使用自定义图标
    【翻译】Siesta事件记录器入门
    【翻译】使用新的Sencha Cmd 4命令app watch
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632192.html
Copyright © 2011-2022 走看看