poj 3252 Round Numbers

来源:互联网 发布:excel vba sql查询 编辑:程序博客网 时间:2024/06/04 20:42

C - Round Numbers
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu
Submit Status

Description

The cows, as you know, have no fingers or thumbs and thus are unable to play Scissors, Paper, Stone' (also known as 'Rock, Paper, Scissors', 'Ro, Sham, Bo', and a host of other names) in order to make arbitrary decisions such as who gets to be milked first. They can't even flip a coin because it's so hard to toss using hooves.

They have thus resorted to "round number" matching. The first cow picks an integer less than two billion. The second cow does the same. If the numbers are both "round numbers", the first cow wins,
otherwise the second cow wins.

A positive integer N is said to be a "round number" if the binary representation of N has as many or more zeroes than it has ones. For example, the integer 9, when written in binary form, is 1001. 1001 has two zeroes and two ones; thus, 9 is a round number. The integer 26 is 11010 in binary; since it has two zeroes and three ones, it is not a round number.

Obviously, it takes cows a while to convert numbers to binary, so the winner takes a while to determine. Bessie wants to cheat and thinks she can do that if she knows how many "round numbers" are in a given range.

Help her by writing a program that tells how many round numbers appear in the inclusive range given by the input (1 ≤ Start < Finish ≤ 2,000,000,000).

Input

Line 1: Two space-separated integers, respectively Start and Finish.

Output

Line 1: A single integer that is the count of round numbers in the inclusive range Start.. Finish

Sample Input

2 12

Sample Output

6

Round Number 是指一个十进制数转化成二进制后0的数目大于等于1的数目的数。

PS:所给十进制数为正整数。

 

RN[a,b] =RN[0,b+1]-RN[0,a]=RN[0,b]-RN[0,a-1];

 

思路:先把所给的数转化成二进制数,并且求出长度len,利用加法原理,可以先求出长度小于len的RN,再求出长度等于len的RN,两者相加即可。

例如给定一个数12,二进制数为(1100)b,二进制数的最高位必定为1.

先求长度小于四的RN的个数,

当长度为3时,RN共有C(2,2);  长度为2 时,RN共有C(1,1);  为1时,有0个。

再求长度为四的RN的个数,即当后3位至少存在两位为0,得C(2,3) + C(3,3);

 

利用此公式进行打表!

 

令L为长度,i为当前改变的“1”的位置,如图中的位置4,zero为0的计数(绝对计数、不包含被改变的第四位数1),a为需要填数的位置(下图中的虚线框)中1的个数,b为需要填数的位置中0的个数。


Zero + 1 是指把当前要改变位的1变成0

这个式子说明了,至少要填那么b个零,也就是L/2-(zero+1),注意奇偶!!!


#include <stdio.h>int c[33][33];int bin[35];//存放十进制转换成二进制后的数 void Init(){int i,j;//求前32项组合数 for(i = 0; i <= 32; i ++){for(j = 0; j <= i; j ++){if(!j || i == j)c[i][j] = 1;elsec[i][j] = c[i - 1][j] + c[i - 1][j - 1];}}}void Binary(int n){bin[0] = 0;while(n){bin[ ++ bin[0]] = n % 2;n /= 2;}}int RoudNumber(int n){int i,j,count = 0;if(n <= 1)return 0;Binary(n);//求所有长度小于bin[0]的RoudNumber的数目 for(i = 1; i < bin[0] - 1; i ++){//bin[0]-1表示去掉最高位 for(j = i / 2 + 1; j <=i; j ++){//去掉最高位后,后面只需保证有i/2 + 1个0即可保证此数为RN; count += c[i][j]; }}int zero = 0;//zero为当前绝对零的数目,不包含当前要变化的位置,即第i位 for(i = bin[0] - 1; i >= 1; i --){if(bin[i]){for(j = (bin[0] + 1) / 2 - (zero + 1); j <= i - 1; j ++){count += c[i - 1][j];}}elsezero ++;}return count;}int main(){int a,b;Init();while(~scanf("%d%d",&a,&b)){printf("%d\n",RoudNumber(b + 1) - RoudNumber(a ));}}


0 0
原创粉丝点击