码迷,mamicode.com
首页 > 其他好文 > 详细

P1582 倒水

时间:2018-08-19 10:55:20      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:class   还需要   main   math   inline   初始化   strong   表示   lin   

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


因为水杯只有水量相等的才能合成,所以一定是\(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\n", ans);
    return 0;
}

P1582 倒水

标签:class   还需要   main   math   inline   初始化   strong   表示   lin   

原文地址:https://www.cnblogs.com/Garen-Wang/p/9499386.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!