链接:点击打开链接
题意:定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2^(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字,给出a,b,求出0~b有多少个不大于f(a)的数
代码:
#include <map>
#include <set>
#include <queue>
#include <string>
#include <math.h>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const int siz=15005;
int A,a[15],dp[10][10][siz];
int sol(){
int ans=0,op=1;
while(A){
ans+=(A%10)*op;
op<<=1;
A/=10;
}
return ans;
}
int dfs(int pos,int pre,int sum,int lim,int tmp){
int i,u,ans=0;
if(pos==0)
return 1;
if(dp[pos][pre][sum]!=-1&&lim==0)
return dp[pos][pre][sum];
u=lim?a[pos]:9;
for(i=0;i<=u;i++){
if(sum-i*(1<<(pos-1))<0)
continue;
ans+=dfs(pos-1,i,sum-i*(1<<(pos-1)),lim&(i==u),tmp*10+i);
}
if(lim==0)
dp[pos][pre][sum]=ans;
return ans;
} //记一下小于等于sum的个数
int cal(int x){
int pos=0;
while(x){
a[++pos]=x%10;
x/=10;
}
return dfs(pos,0,A,1,0);
}
int main(){
int T,r,i,cas;
scanf("%d",&T);
memset(dp,-1,sizeof(dp));
for(cas=1;cas<=T;cas++){
scanf("%d%d",&A,&r);
A=sol();
printf("Case #%d: %d\n",cas,cal(r));
}
return 0;
}