P10892 题解
我们发现,在 \(n\) 的二进制表示的末尾为 \(1\) 时会纠结,所以要尽量减少 \(1\) 的个数。
在 \(n\) 为偶数时,直接除以 \(2\)。
在 \(n\) 为奇数时,我们要先选择 \(+1\) 或 \(-1\),再除以 \(2\)。
分析 \(+1\) 操作对 \(n\) 在二进制下的作用:将末尾连续的 \(1\) 变为 \(0\),并把最近的 \(0\) 变为 \(1\)。此时我们发现,可以通过 \(+1\) 减少 \(1\) 的个数。
但是,当 \(n\) 的二进制表示的末尾为 \(01\) 时,\(+1\) 只会把末尾的 \(1\) 向高位移动一位,所以此时要 \(-1\)。
#include <iostream>
#include <unordered_map>
using namespace std;
using i64 = long long;
unordered_map<i64, int> ans;
int cnt(i64 x)
{
if (x == 0)
return ans[0] = 0;
else if (x == 1)
return ans[1] = 1;
else if (ans.contains(x))
return ans[x];
if (x & 1) {
unsigned long long a = (x + 1) >> 1, b = (x - 1) >> 1;
return cnt((x & 3) == 3 ? a : b) + 1;
} else
return cnt(x >> 1);
}
int main()
{
int t;
cin >> t;
while (t-- > 0) {
i64 x;
cin >> x;
cout << cnt(x) << '\n';
}
return 0;
}

浙公网安备 33010602011771号