poj 2453

考察的是位运算,要求输入的N,找一个最小的大于N的数,并且

其转换成2进制后1的个数不变

思路:记录从右往左最第一组连续1的长度,然后将右边连续的0取反加1

再将原先记录的1的长度减少1,加回原来的数

/*
eg. n=10011100
m=100111
m=100 t=3;
m=11
n=10011111+1=10100000
n=n+m=10100011
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <climits>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <queue>
#include <vector>
#include <stack>
using namespace std;

int main()
{
int n, m, t; //t表示从右往左第一组连续的1的个数
while(scanf("%d", &n), n)
{
m=n;t=0;
while(!(m&1)) m=m>>1; //去右边连续0
while(m&1) {m=m>>1; t++;} //去右边连续的1并记录位数
m=0;t--;
while(t) {m=(m<<1)+1; t--;}
n=(n|(n-1))+1+m;
printf("%d\n", n);
}
}
原文地址:https://www.cnblogs.com/FreeAquar/p/2106527.html