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;
}
posted @ 2025-08-02 16:18  David9006  阅读(6)  评论(0)    收藏  举报