【题解】F(x)

来源:互联网 发布:淮安seo大牛 编辑:程序博客网 时间:2024/05/22 09:41

F(x)

Description

对于具有n位数 (AnAn-1An-2 ... A2A1)的十进制数x,我们将其权值定义为F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1。现在给出两个数字A和B,请计算0和B之间有多少数字,其权值不超过F(A)。


Input

第一行有一个数字T(T <= 10000),表示测试用例数。

对于每个测试用例,有两个数字A和B(0 <= A,B < 109


Output

对于每个样例,您应该首先输出”Case #t: ”,不带引号。 t是从1开始的案例编号。然后输出答案。


Sample Input

3

0 100

1 10

5 100


Sample Output

Case #1: 1

Case #2: 2

Case #3: 13


记忆化搜索:
对于dfs(len,val,full)
len表示搜到第几位,
val代表当前的函数值,
full代表上一位是否等于num[len+1]。

代码:
#include <cstdio>int m,a,b,t,cases,num[11],f[11][10001];int calc(int x){int ans=0,muti=2;while(x){ans+=x%10*muti;x/=10;muti<<=1;}return ans;}int dfs(int len,int val,bool full){if(len==0)return val<=a;if(val>a)return 0;if(!full && f[len][a-val])return f[len][a-val];int sum=0;for(int i=0;i<=(full?num[len]:9);++i)sum+=dfs(len-1,val+i*(1<<len),full&&i==num[len]);if(!full)f[len][a-val]=sum;return sum;}int solve(int n){num[0]=0;while(n){num[++num[0]]=n%10;n/=10;}return dfs(num[0],0,true);}int main(){scanf("%d",&t);while(~scanf("%d%d",&m,&b)){++cases;a=calc(m);printf("Case #%d: %d\n",cases,solve(b));}}

原创粉丝点击