POJ 2453 An easy problem 【位运算】

题目

As we known, data stored in the computers is in binary form. The problem we discuss now is about the positive integers and its binary form.
Given a positive integer I, you task is to find out an integer J, which is the minimum integer greater than I, and the number of '1’s in whose binary form is the same as that in the binary form of I.
For example, if “78” is given, we can write out its binary form, “1001110”. This binary form has 4 '1’s. The minimum integer, which is greater than “1001110” and also contains 4 '1’s, is “1010011”, i.e. “83”, so you should output “83”.

大意:给定一个数字,求解比这个数大,且二进制数中1的个数相同的数字

输入

One integer per line, which is I ( 1 ≤ I ≤ 1000000 ) I (1 \le I \le 1000000) I(1I1000000).
A line containing a number “ 0 0 0” terminates input, and this line need not be processed.

输出

One integer per line, which is J J J.

输入样例

1
2
3
4
78
0

输出样例

2
4
5
8
83

题目分析

本题主要分析了位运算的方法。首先可对输入的数查找其中最小的“ 01 01 01"位置,通过置换为” 10 10 10“来达到找出最小的比原数字大的,二进制中“ 1 1 1“的个数相同的数。
可以通过将数“ n n n”与其负数” − n -n n“相与得到满足条件的最小数。即 x = n & ( − n ) x=n \& (-n) x=n&(n)
例如: n = 0110110 n = 0110110 n=0110110,则 x = 2 x = 2 x=2;
x + n x+n x+n时,得 0111000 0111000 0111000.此时更变的” 01 01 01“之后的数全为 0 0 0.
要恢复少去的 1 1 1,可将 x + n x+n x+n与原数 n n n进行异或并且要移至低位(得到最小的数)
例如: ( x + n ) ⊕ n = 0001111 (x+n)\oplus n = 0001111 (x+n)n=0001111,随后移位 ( x + n ) ⊕ n / x = 0000111 (x+n)\oplus n/x=0000111 (x+n)n/x=0000111
但又因为 x + n x+n x+n将” 01 01 01“改成了” 10 10 10”,所以在异或时会多出2个” 1 1 1”.因此还需对结果右移两位。
最后,将得到的数与 x + n x+n x+n相加即可。即 x + n + ( ( ( x + n ) ⊕ n / x ) > > 2 ) x+n+(((x+n)\oplus n/x)>>2) x+n+(((x+n)n/x)>>2); 得 0111001. 0111001. 0111001.

代码

#include <iostream>

using namespace std;

int main()
{
	int n;
	while(scanf("%d",&n)&&n){
		int x = n & (-n);
		int ans = x+n+((n^(x+n))/x>>2);
		cout << ans<<endl;
	}
	return 0;
}

运行结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

registor11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值