CF1661B

此题不可以打表……

不过通过打表可以发现,每个数最多变换 15 次,

那么枚举一共乘了多少次,设乘了 $p$ 次后离 $0$ 还要多加 $x$ 个 $1$,

直接加肯定不划算,

若在一开始加上 $1$ 再乘 $2$,则最后会额外加上 $2^p$,

若在乘了一次 $2$ 后加 $1$ 再乘 $2$,则到最后会额外加上 $2^{p-1}$,

这……是不是有点像二进制?没错!

具体实现还是得开代码:

#include <cstdio>
#include <iostream>
using namespace std;

const int mod = 32768;

int solve (int x, int p) { // solve (x, p) 就是 x 已经乘了 p 个 2 后,通过在个地方加 1 后得到了 0 的最小代价。
    if (x == 0) return p;
    int y = mod - x, use = 0;
    int ans = 0;
    while (y && use < p) { // 注意:use < p,因为至多乘 2^p。
        if (y & 1) ans ++;
        y >>= 1; use ++;
    }
    ans += y; // 当 use == p 时,现在的 y 就一定要一开始加,不能再减。
    return ans + p; // 记得要加 p 哦!
}

int main() {
    int n; scanf ("%d",&n);
    for (int i = 1; i <= n; ++i) {
        int x; scanf ("%d", &x);
        int mini = 20;
        int now = x; mini = min (mini, solve (now, 0));
        for (int i = 1; i <= 15; ++i) {
            now = now * 2 % mod;
            mini = min (solve (now, i), mini);
        }
        printf ("%d ", mini);
    }
    return 0;
}
posted @ 2022-04-12 11:31  wangzhongyuan  阅读(21)  评论(0)    收藏  举报  来源