Same binary weight
-
描述
-
The binary weight of a positive integer is the number of 1's in its binary representation.for example,the decmial number 1 has a binary weight of 1,and the decimal number 1717 (which is 11010110101 in binary) has a binary weight of 7.Give a positive integer N,return the smallest integer greater than N that has the same binary weight as N.N will be between 1 and 1000000000,inclusive,the result is guaranteed to fit in a signed 32-bit interget.
-
输入
-
The input has multicases and each case contains a integer N.
输出
- For each case,output the smallest integer greater than N that has the same binary weight as N. 样例输入
-
1717 4 7 12 555555
样例输出
-
1718 8 11 17 555557
思路:
首先打一个表:
1717
11010110101
1718
11010110110
4
0100
8
1000
7
0111
11
1011
12
01100
17
10001
555555
10000111101000100011
555557
10000111101000100101
从表中可以找到一个规律就是将二进制的第一个出现的01变成10然后再将01之后的所有的1都移到最右边。
上代码:
#include<map> #include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<sstream> #include<set> #include<stack> #include <bitset>//这里要用到bitset函数所以一定要加这个头文件 using namespace std; int main() { int n; while(~scanf("%d",&n)) { bitset<32>bt(n);//首先将n变成二进制并保留32位 int count=0,flag; for(int i=0;i<32;i++) { if(bt[i]==1) { count++;//统计在找到01之前有多少1以便于后面将01后面的1全部移到最右边 } if(bt[i]==1&&bt[i+1]==0)//找到第一个01将其变成10并用flag标记 { bt[i]=0; bt[i+1]=1; flag=i; break; } } for(int i=0;i<count-1;i++)//01之后的count-1个1移到最右边 { bt[i]=1; } for(int i=count-1;i<flag;i++)//其余的都变成0 { bt[i]=0; } printf("%d\n",bt.to_ulong());//将二进制变成十进制 } return 0; }
这里用到了两个函数bitset函数将十进制变成二进制,bt.to_ulong()将二进制变成十进制
这里还可以用位运算首先介绍一下按位与&和按位或|
按位与&就是当对应的两个二进制位均为1时结果才为1,否则的话为0.
按位或|就是对应的两个二进制位只要有一个为1结果就为1,全为0结果就为0
然后是这道题的算法:
<p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; line-height: 19.5px; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">1. 约定 x 是输入的 N,如 x = 1717,则 -x = -1717,二进制中 -x = -1717(1001 0100 1011 原码取反加一)</p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; line-height: 19.5px; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">2. 令 b = x & (-x),得到 x 中最后一个 “1” 的位置</p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; line-height: 19.5px; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">3. 令 t = x + b, 产生进位,实现 “01” 改变为 “10”</p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; line-height: 19.5px; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">4. 令 s = t ^ x, 得到进位过程中发生变动的位</p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; line-height: 19.5px; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">5. (s >> 2),“10” -》 "10" 后这两位就不要再去改变它们了,所以右移 2 位(去掉这两位)</p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; line-height: 19.5px; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">6. 令 k = (s >> 2)/ b,除去“01” -》 “10”这两位外,将“01”以后至最后一个“1“(包含最后一个”1“)之间的所有”1“移动至最后,原理见下</p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; line-height: 19.5px; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);">7. 那么最后的结果就是 t | k</p><p style="margin: 10px auto; padding-top: 0px; padding-bottom: 0px; line-height: 19.5px; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: rgb(254, 254, 242);"> </p>具体代码自己想一想吧。
-
The input has multicases and each case contains a integer N.