A EASY PROBLEM

给定一个正整数 N,求最小的、比 N 大的正整数 M,使得 M 与 N 的二进制表示中有相同数目的1。
举个例子,假如给定的 N 为 78,其二进制表示为 1001110,包含 4 个 1 ,那么最小的比 N 大的并且二进制表示中只包含 4 个 1 的数是 83 ,其二进制是 1010011,因此 83 就是答案。

输入输出格式
输入格式
输入若干行,每行一个数 n,输入"0"结束。
输出格式
输出若干行对应的值。

输入输出样例1
输入

1
2
3
4
78
0
输出

2
4
5
8
83
说明提示
1≤n≤10 
6

/*

一次从下一个数开始递增枚举

计算给定十进制数的二进制

判断两个数二进制是不是相等

*/

#include <iostream>

using namespace std;

//计算给定十进制正整数转换为二进制中含有的1

//代码原理进制转换中是循环逆向取余数法

int countOnes(int N){

    int res=0;

    while(N){

        if(N%2==1)

        res++;

        N/=2;

    }

    return res;//记录十进制数转为二进制数中有多少位1

}

/*

//计算一个数的二进制表示中 1 的个数

//代码的原理是位运算

int countOnes(int num) {

    int count = 0;  // 用于记录二进制表示中 1 的个数,初始化为 0

    while (num) {  // 当 num 不为 0 时,继续循环,因为当 num 变为 0 时,说明已经检查完所有的位

        count += num & 1;  // 使用按位与运算(&)回检查 num对应的二进制数 的最低位(最靠右边)是否为 1

        num >>= 1;  // 将 num 右移一位,相当于去掉最低位,以便检查下一位(也就是之前的靠左一位代替成了的现在最低位)

        //比如 二进制数100 通过>>左移 变成了10

    }

    return count;  // 返回统计得到的 1 的个数

}

//按照位运算中的&&(按位与)||(按位或)···

//这算一种技巧,希望记住,我想信万千智慧始于记忆,理解也是为了更好的记忆

*/

//判断两个数二进制含有的1是不是相等

int findNextNum(int N){

    int target=countOnes(N);

    int i=N+1;

    while(1){

        //死循环并不是一无是处,有点像简单枚举

//从贪心算法角度解释,就是现解决一个小问题就算一次小成功,知道将所有小问题都解决,就算完成任务了

        if(countOnes(i)==target)

        break;//找到了,不会再执行下一语句,直接跳出

        i++;

    }

    return i;

}

int main(){

    int num;

    while(cin>>num&&num!=0)

    cout<<findNextNum(num)<<endl;

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值