http://codeforces.com/contest/722/problem/D
题目大意:给你一个没有重复元素的Y集合,再给你一个没有重复元素X集合,X集合有如下操作 ①挑选某个元素*2 ②某个元素*2+1
问:找到一个X集合,里面的元素与Y的元素可以相互转换,且X的max要尽量小。
思路:二分答案找就好了。从Y开始进入,不需要考虑奇偶数,反正每次都/2就行了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//看看会不会爆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 ") 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; }