简单数位DP,f[i][j]表示i位的数字有多少个数权值小于j,i位的数是实际意义的i位数,就是是以1--9开头,不包括0、
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <map>
#include <string>
#define eps 1e-8
#define LL long long
#define myabs(x) ((x)>0?(x):(-(x)))
using namespace std;
const int inf=0x3f3f3f3f;
const int maxm=5000;
int w[]={1,2,4,8,16,32,64,128,256};
LL f[15][maxm+10];
int B[15];
int main()
{
int T;
cin>>T;
int i,j,k,p;
for(i=0;i<=maxm;i++) f[0][i]=1;
for(i=1;i<=9;i++)
{
for(j=0;j<=maxm;j++)
{
for(k=1;k<=9&&((1<<(i-1))*k)<=j;k++)
{
for(p=0;p<i;p++)
f[i][j]+=f[p][j-(1<<(i-1))*k];
}
}
}
int a,b;
int cas=0;
while(T--)
{
scanf("%d%d",&a,&b);
int len=0,mul=1,sum=0,sum2=0;
while(a)
{
sum+=(a%10)*mul;
mul*=2;
a/=10;
}
while(b)
{
B[len++]=b%10;
b/=10;
sum2+=B[len-1]*w[len-1];
}
LL ans=0;
if(sum2<=sum) ans++;
if(len==1&&B[0]==0) { ans=f[0][sum]; }
else
{
for(i=len-1;i>=0;i--)
{
for(j=0;j<B[i]&&(j*w[i]<=sum);j++)
{
for(k=i;k>=0;k--)
{
ans+=f[k][sum-w[i]*j];
}
// printf("%d %d\n",j,ans);
}
sum-=(w[i]*B[i]);
}
}
printf("Case #%d: %I64d\n",++cas,ans);
}
return 0;
}