文章目录
- 1. 题目
- 1.1 题目链接
- 1.2 题目大意
- 1.3 解题思路
- 2. Accepted 代码
1. 题目
1.1 题目链接
http://poj.org/problem?id=2453
1.2 题目大意
一个数x的二进制表示有n个1,求一个有相同个数1的二进制数(比x大,且要最小的)
1.3 解题思路
- 求出该数的二进制表示
- 从低位往高位找到第一个为1的位 i ,检查其下一位 i+1
- i+1 位值为 0,直接交换01,结束查找
- i+1 位值为1,将 i 位的1不断地与前面的交换,换至最低位
- 重复以上过程
2. Accepted 代码
/*** @description: 贪心应用poj2453* @author: michael ming* @date: 2019/7/2 20:46* @modified by:*/
#include <cstring>
#include <iostream>
using namespace std;int calc(int num, int *binarynum)
{int i = 0, j, k, value = 0;while(num != 0){binarynum[i++] = num % 2;//数组存储的是该数的二进制的反序序列num = num/2;}k = i;//k记录最后一个有效位的下一位for(i = 0; i < k; ++i){if(binarynum[i] == 0)continue;//找到为1的iif(binarynum[i+1] == 0)//如果i的下一个为0{swap(binarynum[i],binarynum[i+1]);//交换完成寻找break;}for(j = i; j >= 1; --j)//否则将i处的1换到最开始{swap(binarynum[j],binarynum[j-1]);}}for(i = k; i >= 0; --i)//计算对应的10进制数值//最后一位k-1可能进位到k,所以i从k开始value = value*2 + binarynum[i];return value;
}
int main()
{int binarynum[30];//数据大小不会超过30位2进制int num;while(cin >> num && num){memset(binarynum,0,30*sizeof(int));cout << calc(num,binarynum) << endl;}return 0;
}