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

[LG1582] 倒水

时间:2019-06-15 09:32:57      阅读:88      评论:0      收藏:0      [点我收藏+]

标签:line   bit   mes   移动   不用   amp   namespace   mat   pac   

分析

考虑 \(n\) 的二进制数下的 \(1\) 的个数为 \(bitcount(n)\) . 则 \(n\) 最少可以合并为 \(bitcount(n)\) 杯水.

如果 \(bitcount(n)>k\) ,则让 \(n\) 的最右端的 \(1\) 向左进位(有可能与左边的 \(1\) 合并,也可能只是单纯地把 1 的位置向左移动),即 \(n=n+lowbit(n)\) . 直到 \(bitcount(n)\leq k\) ,输出累加值即可。

计算 \(bitcount(n)\)

按位归并,将二进制位下 1 的个数依次归并为四,八,十六,三十二进制位。

具体来讲,类比八位二进制下 \((01011011)_2\)

  • 将 1,3,5,7 位的数分别加至 2,4,6,8 位上: \((0011)_2+(1101)_2=(1112)_4\) .
  • 将 1,3 位的数分别加至 2,4 位上: \((11)_4+(12)_4=(23)_8\) .
  • 将 1 位的数加至 2 位上: \((2)_8+(3)_8=(5)_{16}=(5)_{10}=5\) .

同理,对于三十二位,则按位归并,按位相加(进制数为 \(2^i\) ,不用管进位的问题)至三十二进制数,再改为十进制即可。

事实上,在位上操作完之后,直接输出就是十进制结果。

代码实现

#include<cstdio>
using namespace std;
int n,k,ans;
int bitcount(int x){x=((x>>1)&0x55555555)+(x&0x55555555);
    x=((x>>2)&0x33333333)+(x&0x33333333);
    x=((x>>4)&0x0f0f0f0f)+(x&0x0f0f0f0f);
    x=((x>>8)&0x00ff00ff)+(x&0x00ff00ff);
    x=((x>>16)&0x0000ffff)+(x&0x0000ffff);
    return x;
}
int main(){scanf("%d%d",&n,&k);
    while(bitcount(n)>k)ans+=n&(-n),n+=n&(-n);
    printf("%d",ans);
    return 0;
}

[LG1582] 倒水

标签:line   bit   mes   移动   不用   amp   namespace   mat   pac   

原文地址:https://www.cnblogs.com/sshwy/p/11026369.html

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