Nyist 416 -- Same binary weight

原题是 : TopCoder SRM 416 DIV 2 Same binary weight

 

先看看这几个例子:

1717(0110 1011 0101),下一位是 1718(0110 1011 0110

767(0010 1111 1111),下一位是 895(0011 0111 1111)

348(0001 0101 1100),下一位是 355(0001 0110 0011

其中不难发现一个规律,从右起的第一个“01”改变为“10”,并且在“01”的后面所有的“1”都移动至最后,事实上,这个就是解题的关键点,那么整个问题求解的核心就转移到这两个子问题:

1. 将右起第一个“01”,改变为“10”

2. 将该“01”后面的所有“1”移动至最后

 

位运算的解法

1. 约定 x 是输入的 N,如 x = 1717,则 -x = -1717,二进制中 -x = -1717(1001 0100 1011 原码取反加一)

2. 令 b = x & (-x),得到 x 中最后一个 “1” 的位置

3. 令 t = x + b, 产生进位,实现 “01” 改变为 “10”

4. 令 s = t ^ x, 得到进位过程中发生变动的位

5.  (s >> 2),“10” -》 "10" 后这两位就不要再去改变它们了,所以右移 2 位(去掉这两位)

6. 令 k = (s >> 2)/ b,除去“01” -》 “10”这两位外,将“01”以后至最后一个“1“(包含最后一个”1“)之间的所有”1“移动至最后,原理见下

7. 那么最后的结果就是 t | k

 

汇编中的除法原理:

二进制的除法本质是通过重复减法运算实现

即通过重复”从被除数的高位依次取出每一位, 被取出的数据加上上次的减法结果*2,

然后减去除数”的处理, 求出除法结果

 

那么如此一来,“01”以后至最后一个“1“(包含最后一个”1“)之间的所有”1“移动至最后,代码就不贴了,自己写

转载于:https://www.cnblogs.com/yewei/archive/2012/09/21/2696499.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值