您的位置:首页 > 理论基础 > 数据结构算法

数据结构专题训练一 C Bits

2014-03-07 16:37 218 查看
不知道哪里的题,用大数才过,简直丧心病狂!

Problem J

Bits

Input:
Standard Input
Output: Standard Output

A bit is a binary digit, taking a logical value of either "1" or "0" (also referred to as "true" or "false" respectively). And every decimal number has a binary representation which is actually a series of bits.
If a bit of a number is “1” and it's next bit is also “1” then we can say that the number has a 1 adjacent bit. And you have to find out how many times this scenario occurs for all numbers up to N.

Examples:
Number Binary Adjacent Bits
12 1100 1
15 1111 3
27 11011 2

Input
For each test case, you are given an integer number (0 <= N <= ((2^63)-2)), as described in the statement. The last test case is followed by a negative integer in a line by itself, denoting the end of input file.

Output

For every test case, print a line of the form “Case X: Y”, where X is the serial of output (starting from 1) and Y is the cumulative summation of all adjacent bits from 0 to N.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<set>
using namespace std;

#define mxn 100
#define inf 0x3f3f3f3f
#define eps 1e-8
#define LL long long 
#define ull unsigned long long
#define MP make_pair
struct bign {
	int x[1020], len;
	bign(){
		x[0] = 0, len = 0;
	}
	bign operator + ( const bign & b ) const {
		int i, carry;
		bign c;
		for( i = carry = 0; i <= len || i <= b.len || carry; ++i ) {
			if( i <= len )
				carry += x[i];
			if( i <= b.len )
				carry += b.x[i];
			c.x[i] = carry % 10;
			carry /= 10;
		}
		c.len = i - 1;
		return c;
	}
	bign operator + ( const LL& b ) const {
		int i, carry = b;
		bign c;
		for( i = 0; i <= len || carry; ++i ) {
			if( i <= len )
				carry += x[i];
			c.x[i] = carry % 10;
			carry /= 10;
		}
		c.len = i - 1;
		return c;
	}
	bign operator * ( const LL & b ) const {
		int i, carry;
		bign c;
		for( i = carry = 0; i <= len || carry; ++i ) {
			if( i <= len )
				carry += b * x[i];
			c.x[i] = carry % 10;
			carry /= 10;
		}
		i --;
		while( i && ! c.x[i] )
			i--;
		c.len = i;
		return c;
	}
	void display() {
		for( int i = len; i >= 0; -- i ) {
			printf( "%d", x[i] );
		}
	}
}p[mxn], dp[mxn], sum[mxn], num[mxn];
// p[i] 表示2的i次方, dp[i]表示二进制位数为i+1的所有数的相邻1的对数和
// sun[i]表示 小于2的i+1次方的所有数的相邻1的对数和
// num[i]表示n的前i个位一共有多少数
int a[100];
void init() {
	p[0] = p[0] + 1;
	for( int i = 1; i < 64; ++i )
		p[i] = p[i-1] * 2;
	dp[1] = dp[1] + 1;
	sum[1] = sum[1] + 1;
	for( int i = 2; i < 64; ++i ) {
		dp[i] = dp[i-1] * 2 + p[i-2];
		sum[i] = sum[i-1] + dp[i];
	}
}
int main() {
	init();
	LL n;
	int cas = 1;
	while( cin >> n && n >= 0 ) {
		LL s = n;
		int len = 0;
		a[0] = 0;
		while( s > 0 ) {
			a[len++] = s % 2;
			s >>= 1;
		}
		memset( num, 0, sizeof( num ) );
		num[0] = num[0] + a[0] + 1;
		for( int i = 1; i < len; ++i ) {
			if( a[i] )
				num[i] = num[i-1] + p[i];
			else
				num[i] = num[i-1];
		}
		bign ans;
		for( int i = len - 1; i >= 0; --i ) {
			if( i && a[i] )
				ans = ans + sum[i-1];
			if( i == len - 1 )
				continue;
			if( a[i] && a[i+1] )
				if( i )
					ans = ans + num[i-1];
				else
					ans = ans + 1;
		}
		printf( "Case %d: ", cas++ );
		ans.display();
		printf( "\n" );
	}
	return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: