Same binary weight 位操作 bitset用法 STL

Same binary weight

时间限制: 300 ms  |  内存限制: 65535 KB
难度: 3
描述

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
来源
topcoder
上传者
骆魁永
大意是找出n转化为2进制时有相同的1,离得最近的那个;
直接用BitSet超时:
#include<iostream>
#include<bitset>
using namespace std;
int main()
{
	int n;
	while(cin>>n)
	{
		bitset<32> b(n);//将n转化为二进制
		int temp1=b.count(),temp2;
		for(int i=n+1;;++i)
		{
			bitset<32> c(i);
			temp2=c.count();//统计1的个数
			if(temp1==temp2)
			{
				cout<<i<<endl;
				break;
			}
		}
	}
}

先看看这几个例子:

1717(0110 1011 0101),下一位是 1718(0110 1011 0110

767(0010 1111 1111),下一位是 895(0011 0111 1111)

348(0001 0101 1100),下一位是 355(0001 0110 0011

其中不难发现一个规律,从右起的第一个“01”改变为“10”,并且在“01”的后面所有的“1”都移动至最后,事实上,这个就是解题的关键点,那么整个问题求解的核心就转移到这两个子问题:

1. 将右起第一个“01”,改变为“10”

2. 将该“01”后面的所有“1”移动至最后

所以直接操作二进制位就ok;
#include<iostream>
#include<bitset>
using namespace std;
int main()
{
	int n;
	while(cin>>n)
	{
		bitset<32> b(n);
		//cout<<b<<endl;
		//for(int k=0;k<32;++k)
		//cout<<b[k]; 
		//cout<<endl;
		int i,cont=0;
		for(i=0;i<32;i++)
		{
			if(b[i]==1)
				cont++;
			if(b[i]==1&&b[i+1]==0)
			{
				bool t;
				t=b[i];
				b[i]=b[i+1];
				b[i+1]=t;
				break;
			}
		}
		int j=i-1;
		for(i=0;i<=j;i++)
		{
			if(i<cont-1)
				b[i]=1;
			else
				b[i]=0;
		}
		//cout<<b<<endl;
		cout<<b.to_ulong()<<endl; 

	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值