Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) D. Generating Sets __ dfs+优先队列+贪心

来源:互联网 发布:金山数据恢复账号 编辑:程序博客网 时间:2024/06/02 19:29

D. Generating Sets
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard 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:

  1. Take any integer xi and multiply it by two, i.e. replace xi with xi.
  2. Take any integer xi, multiply it by two and add one, i.e. replace xi with 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
51 2 3 4 5
output
4 5 2 3 1 
input
615 14 3 13 1 12
output
12 13 14 7 3 1 
input
69 7 13 17 5 11
output
4 5 2 6 3 1

Source

Intel Code Challenge Elimination Round (Div.1 + Div.2, combined)


My Solution

dfs+优先队列+贪心

向把数读入到priority_queue, 同时用 map<int, bool> mp来标记这些数字,出现过。

然后每次贪心的取最大的值,u = pq.top(), mp[u] = false; 然后dfs的向下推可行的一步,比如 13 到 6 如果可以就标记并返回,否者继续向下找。

如果最大值已经不能向下推了,则pq里维护着的元素就是答案了。

此外,这个方法对于 n == 1时要特殊处理, 不然n == 1的时候 一直mp[1] = false,然后dfs(1),这样每次flag都被标记跳不出循环了

总复杂度 O(nlognlogn)


#include <iostream>#include <cstdio>#include <map>#include <queue>using namespace std;typedef long long LL;const int maxn = 5e5 + 8;int v;map<int, bool> mp;priority_queue<int> pq;bool flag;/*//一次性放好不大行,会出问题,比如样例3,//还是用pq来维护每次把最大的向下推一次,void dfs(LL x, int i){    if(x == 1){        if(mp[x] == false){            mp[x] = true;            v[i] = x;            flag = true;        }        return;    }    if(x & 1){            dfs((x - 1) / 2, i);            if(!flag){                if(mp[x] == false){                    mp[x] = true;                    v[i] = x;                    flag = true;                }            }            return;    }    else{            dfs(x / 2, i);            if(!flag){                if(mp[x] == false){                    mp[x] = true;                    v[i] = x;                    flag = true;                }                return;            }    }    //......    if(!flag){        mp[x] = true;        v[i] = x;    }}*///用priority_queue 来维护, 每次取最大值, 向下推一步,//然后重新取最大值, 这样一步一步的往下推//直到最大值不能向下推,得到答案, 因为要求最大值尽可能小, 所以对其它值不做要求//总的复杂度依然是 O(nlogn);inline void dfs(int x){    if(x == 1){        if(mp[x] == false){            mp[x] = true;            v = x;            flag = true;        }        return;    }    if(x & 1){        if(mp[(x - 1) / 2] == false){            mp[(x - 1) / 2] = true;            v = (x - 1) / 2;            flag = true;            return;        }        dfs((x - 1) / 2);    }    else{        if(mp[x / 2] == false){            mp[x / 2] = true;            v = x / 2;            flag = true;            return;        }        dfs(x / 2);    }    //......}int main(){    #ifdef LOCAL    freopen("d.txt", "r", stdin);    //freopen("d.out", "w", stdout);    int T = 3;    while(T--){    #endif // LOCAL    ios::sync_with_stdio(false); cin.tie(0);    int n, u;    cin >> n;    for(int i = 0; i < n; i++){        cin >> v;        mp[v] = true;        pq.push(v);    }    if(n == 1){ cout << 1 << endl; return 0;}  //!    while(true){        u = pq.top();        pq.pop();        mp[u] = false;        flag = false;        //cout << v[i] << " ";        dfs(u);        if(!flag) {pq.push(u); break;}        pq.push(v);        //cout << v[i]<<endl;    }    cout << pq.top(); pq.pop();    while(!pq.empty()){        cout << " " << pq.top();        pq.pop();    }    cout << endl;    #ifdef LOCAL    mp.clear();    cout << endl;    }    #endif // LOCAL    return 0;}

  Thank you!

                                                                                                                                               ------from ProLights 

0 0