For a decimal number x with n digits (A nA n-1A n-2 ... A 2A 1), we define its weight as F(x) = A n * 2 n-1 + A n-1 * 2 n-2 + ... + A 2 * 2 + A 1 * 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).
InputThe 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 < 10 9)OutputFor 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
3 0 100 1 10 5 100
Sample Output
Case #1: 1 Case #2: 2 Case #3: 13
题意:给定了一个数字权值计算公式,问0-b中有多少数字f(x)<f(a);
思路:
dp[pos][num]表示在数位pos之后,f(x)小于等于num的数量
#include<iostream> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<map> #include<set> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #define fuck(x) cout<<#x<<" = "<<x<<endl; #define ls (t<<1) #define rs ((t<<1)+1) using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 100086; const int inf = 2.1e9; const ll Inf = 999999999999999999; const int mod = 1000000007; const double eps = 1e-6; const double pi = acos(-1); int dp[12][5000]; int dig[12]; int fa; int dfs(int pos,int num,bool limit){ if(num<0){ return 0;} if(pos==-1){ return num>=0; } if(!limit&&dp[pos][num]!=-1){ return dp[pos][num];} int up=limit?dig[pos]:9; int ans=0; for(int i=0;i<=up;i++){ ans+=dfs(pos-1,num-i*(1<<pos),limit&&i==up); } if(!limit){dp[pos][num]=ans;} return ans; } int solve(int x){ int pos=0; while (x){ dig[pos++]=x%10; x/=10; } return dfs(pos-1,fa,true); } int cal(int x){ int tmp=1,ans=0; while (x){ ans+=(x%10)*tmp; x/=10; tmp<<=1; } return ans; } int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); int T; scanf("%d",&T); int cases=0; memset(dp,-1,sizeof(dp)); while (T--){ cases++; int a,b; scanf("%d%d",&a,&b); fa=cal(a); printf("Case #%d: %d ",cases,solve(b)); } return 0; }