Round Numbers
Description
你知道的牛没有手指或拇指,因此无法玩石头剪刀布,以便做出任意决定,比如谁首先被挤奶。他们甚至不能翻转硬币,因为很难用蹄子折腾。
因此,他们采取了"Round Numbers"配对。第一只牛选择一个小于20亿的整数,第二只牛做同样的事情。如果数字都是“Round Number”,那么第一头牛就会赢,
否则第二头牛胜。
如果N的二进制表示中0的个数大于或等于1的个数,则正整数N被称为“Round Number”。例如,当以二进制形式写入时,整数9是1001,1001有两个0和两个1;因此,9是一个"Round Number"。整数26是二进制的11010;由于它有两个0和三个1,它不是一个"Round Number"。
显然,奶牛需要一段时间才能将数字转换为二进制,所以获胜者需要一段时间才能确定。Bessie想要作弊,如果她知道在一定范围内有多少“Round Number”,她就可以作弊。
帮助她编写一个程序,告诉输入中给出的包含范围内有多少个“Round Number”(1≤Start≤Finish≤2,000,000,000)。
(原文:
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 ofN 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
1行:两个空格分隔的整数,分别为Start和Finish。
Output
1行:一个整数,它是范围Start..Finish中的"Round Number"的个数
Sample Input
2 12
Sample Output
6
又是一道数位dp的题目。。。
记忆化搜索,以f[a][b][c]记录剩下a位二进制位并且已有b个0,c个1的“Round Number”个数。
搜索过程 dfs(len,c0,c1,full,up0) 中:
len代表还剩下的二进制位的长度,
c0,c1分别代表已有的0和1的数目,
up0代表是否还在前导零中(前导零的数目不计入零的数目中)。
代码:
#include <cstdio>
#define ll long long
ll f[35][35][35];
int num[35];
ll dfs(int len,int c0,int c1,bool full,bool up0)
{
if(!len)
if(up0 || c0>=c1)return 1; else return 0;
if(!up0 && !full && f[len][c0][c1])return f[len][c0][c1];
ll sum=0;
for(int i=0;i<=(full?num[len]:1);++i)
if(up0&&!i)sum+=dfs(len-1,0,0,full&&i==num[len],1);
else
if(i)sum+=dfs(len-1,c0,c1+1,full,0); else sum+=dfs(len-1,c0+1,c1,full&&i==num[len],0);
if(!up0 && !full)f[len][c0][c1]=sum;
return sum;
}
ll work(ll x)
{
num[0]=0;
while(x)
{
num[++num[0]]=x&1;
x>>=1;
}
return dfs(num[0],0,0,1,1);
}
int main()
{
ll a,b;
while(~scanf("%lld%lld",&a,&b))printf("%lld",work(b)-work(a-1));
}