专栏文章
二进制与一 II 题解
P11968题解参与者 15已保存评论 15
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 15 条
- 当前快照
- 1 份
- 快照标识符
- @miqei54f
- 此快照首次捕获于
- 2025/12/04 03:29 3 个月前
- 此快照最后确认于
- 2025/12/04 03:29 3 个月前
出题人题解。
问题可以转换为求比 小的在二进制下有 位为 的最大的 ,及比 大的在二进制下有 位为 的最小的 ,答案则为 。
既然有大小关系的比较,那不妨枚举从最高位开始, 分别在哪一位与 不同。假设当前考虑到第 位(从右往左数),那么对于 来说, 在二进制下,该位必须为 ,此时 此位便为 ,且由于我们应当构造出最大的合法的 ,所以 从第 位开始应当是一段连续的 。 同理,应贪心的将 尽量放在靠右的位上。
Code
CPP#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[65], t;
int sum(int x) {
int ans = 0;
while (x) {
ans += x % 2;
x /= 2;
}
return ans;
}
signed main() {
int T;
cin >> T;
while (T--) {
int n, k;
cin >> n >> k;
int x = n;
if (sum(n) == k) {
cout << 0 << "\n";
continue;
}
t = 0;
while (x) {
a[++t] = x % 2;
x /= 2;
}
if (t <= k)
cout << (1LL << k) - 1 - n << "\n";
else {
int now = 0, one = 0, ans = (1LL << t) + (1LL << (k - 1)) - 1 - n;
for (int i = t; i >= 1; i--) {
bool e = (n & (1LL << i - 1));
if (e) {
int tmp = now * 2;
if (i - 1 < k - one || one > k)
continue;
tmp *= (1LL << i - 1);
tmp += (1LL << (i - 1)) - 1 - ((1LL << (i - 1 - (k - one))) - 1);
one++;
ans = min(ans, n - tmp);
}
now = now * 2 + e;
}
now = 0, one = 0;
for (int i = t; i >= 1; i--) {
bool e = (n & (1LL << i - 1));
if (e)
one++;
else {
int tmp = now * 2 + 1;
if (i - 1 < k - one - 1 || one >= k)
continue;
tmp *= (1LL << i - 1);
if (k - one - 1)
tmp += (1LL << (k - one - 1)) - 1;
ans = min(ans, tmp - n);
}
now = now * 2 + e;
}
cout << ans << "\n";
}
}
}
相关推荐
评论
共 15 条评论,欢迎与作者交流。
正在加载评论...