P1582 倒水

Posted garen-wang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1582 倒水相关的知识,希望对你有一定的参考价值。

二进制题目,第一次正式接触二进制操作。


因为水杯只有水量相等的才能合成,所以一定是(2^i)

这种标志可以用二进制表示,每一位刚好就是上面的表达方式。

把题意翻译到二进制数字上就是:二进制上为1的位数数目

那么问题终于来了:如何数出一个二进制数字上1的多少?

这里有两种方法。

  1. 暴力的。我们可以搞一个数字初始化为1,然后每一次就左移1位,那么我们可以对每一位进行检查,复杂度应该是(O(logn))

  2. 稍有优化的。还记得树状数组中的lowbit函数吗?能够减掉多少次lowbit其实就是有多少个1。

当新得到数字大于(k)时,我们还需要继续枚举。

可以发现如果无脑地加1的话答案不会更优,其实我们可以加一个lowbit

然后就能过了。

代码:

#include<cstdio>

int n, k, ans;
int lowbit(int x)
{
    return x & -x;
}
int main()
{
    scanf("%d%d", &n, &k);
    for(int i = 0; ; )
    {
        int cnt = 0;
        for(int j = 0; (1 << j) <= n; j++) if(n & (1 << j)) cnt++;
        if(cnt <= k) break;
        ans += lowbit(n);
        n += lowbit(n);
    }
    printf("%d
", ans);
    return 0;
}

以上是关于P1582 倒水的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1582 倒水

题解Luogu P1582 倒水 二进制

__builtin_popcount() 函数

数学Vijos P1582 笨笨的L阵游戏

Problem E: 倒水(Water)

经典倒水问题