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

http://codeforces.com/contest/722/problem/D

题目大意:给你一个没有重复元素的Y集合,再给你一个没有重复元素X集合,X集合有如下操作 ①挑选某个元素*2 ②某个元素*2+1

问:找到一个X集合,里面的元素与Y的元素可以相互转换,且X的max要尽量小。

 

思路:二分答案找就好了。从Y开始进入,不需要考虑奇偶数,反正每次都/2就行了。

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 50000 + 5;
int a[maxn], ans[maxn];
int n;

bool check(int maxval){
    map<int, int> m;
    int cnt = 0;
    for (int i = 1; i <= n; i++){
        int myval = a[i];
        while (myval && (myval > maxval || m.count(myval)))
            myval /= 2;///除以2就好了,貌似并不需要考虑+1
        if (myval == 0) return 0;
        m[myval] = 1;
        ans[i] = myval;
    }
    return 1;
}

int main(){
    cin >> n;
    int l = 0, r = 0;
    for (int i = 1; i <= n; i++){
        scanf("%d", a + i); r = max(a[i], r);
    }
    while (l < r){
        int mid = (l + r) / 2;
        if (check(mid)){
            r = mid;
        }
        else l = mid + 1;
    }
    check(l);
    for (int i = 1; i <= n; i++){
        printf("%d ", ans[i]);
    }
    return 0;
}
View Code

 

posted @ 2016-10-02 14:29  知る奇迹に  阅读(151)  评论(0)    收藏  举报