F(x)

For a decimal number x with n digits (AnAn-1An-2 … A2A1), we define its weight as F(x) = An 2n-1 + An-1 2n-2 + … + A2 2 + A1 1. Now you are given two numbers A and B, please calculate how many numbers are there between 0 and B, inclusive, whose weight is no more than F(A).

Input

The first line has a number T (T <= 10000) , indicating the number of test cases.
For each test case, there are two numbers A and B (0 <= A,B < 109)

Output

For every case,you should output “Case #t: “ at first, without quotes. The t is the case number starting from 1. Then output the answer.

Sample Input

1
2
3
4
3
0 100
1 10
5 100

Sample Output

1
2
3
Case #1: 1
Case #2: 2
Case #3: 13

最开始的思路肯定是搜索

首先是对数位的搜索

然后开始思考另外有什么状态是需要往下面传的,那么就只有前面数的和了,因此是二维的,第一维度是数位,第二个维度是sum;

然后思考记忆化,最直观的就是第二维度就是sum,但是这样子的话每一次都需要根据all进行修改;比较特别的是dp里面的sum记录的是all-sum的值,这样做可以有效的利用memset优化;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <iostream>
#include <cstring>

int dp[12][5005];//dp[pos][sum]:对于位置pos的数位,这里的sum存储的是all-当前pos前缀和的差;
int cur[12];
int all;

using namespace std;
int f(int a){//计算F(a)的值
if(a==0)return 0;
int pos=0;
int able[11];
while(a){
able[pos++]=a%10;
a/=10;
}
int result=0;
// int now=1;
for(int i=pos-1;i>=0;--i){
result+=(able[i]<<i);
//now*=2;
}
//cout<<"result:"<<result<<endl;
return result;
}
// pos:当前的数位,sum 当前的和

/*
if(pos<0)return 1;合法;




*/
int dfs(int pos,int sum,bool limit){//这里的sum表示的是到目前数位的前缀和

if(pos<0)return sum<=all;
if(sum>all)return 0;

if(!limit&&dp[pos][all-sum]!=-1)return dp[pos][all-sum];

int up=limit?cur[pos]:9;
int ans=0;
for(int i=0;i<=up;++i){

ans+=dfs(pos-1,sum+i*(1<<pos),limit&&cur[pos]==i);
}
if(!limit)dp[pos][all-sum]=ans;
// cout<<pos<<" "<<sum<<" "<<limit<<" "<<ans<<endl;
return ans;


}




int solve(int a,int b){
// memset(cur,0,sizeof(cur));
all=f(a);
int pos=0;
if(b==0)return 0;
while(b){
cur[pos++]=b%10;
b/=10;
}
// for(int i=pos-1;i>=0;--i){
// cout<<cur[i]<<endl;
// }
int result=dfs(pos-1,0,true);


return result;
}



int main(){
int t;
//cin>>t;
scanf("%d",&t);
memset(dp,-1,sizeof(dp));
for(int i=0;i<t;++i){
int a,b;
scanf("%d%d",&a,&b);
//cin>>a>>b;
int result=solve(a,b);
// printf("Case #%d: %d",i+1,result);
printf("Case #%d: %d\n",i+1,result);
// cout<<"Case #"<<i+1<<": "<<result<<endl;
}
return 0;


}