题目描述
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)
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.
题解
可以观察到位数只有9位,F(x)的值不会超过4599,那么很容易可以得到状态f[pos][sum]
#include<bits/stdc++.h>
using namespace std;
int t,pow2[15];
int a,b;
int len,num[10];
int f[10][10000][2];
void get_fa(int &a){
int x=0,cnt=0;;
while(a){
x+=pow2[cnt++]*(a%10);
a/=10;
}
a=x;
}
int dfs(int s,int sum,bool lim){
if(sum>a) return 0;
if(!s) return 1;
if(f[s][sum][lim]!=-1) return f[s][sum][lim];
int mx= lim ? num[s] : 9 ;
int ret=0;
for(int i=0;i<=mx;i++)
ret+=dfs(s-1,sum+i*pow2[s-1],lim&&i==mx);
return f[s][sum][lim]=ret;
}
int cx(int x){
len=0;
while(x){
num[++len]=x%10;
x/=10;
}
memset(f,-1,sizeof(f));
return dfs(len,0,true);
}
void nice(int i){
scanf("%d%d",&a,&b);
get_fa(a);
//printf("%d
",a);
printf("Case #%d: %d
",i,cx(b));
}
int main(){
pow2[0]=1;
for(int i=1;i<=10;i++) pow2[i]=pow2[i-1]*2;
scanf("%d",&t);
for(int i=1;i<=t;i++) nice(i);
}
然后疯狂TTTTTTT掉
因为对于每组数据都要将f初始化,然后不要脸的去看了博客,
发现可以改变数组状态,第二位定义为与f(x)的差,就只需要在最初初始化,不过不能开lim这一维
简直妙啊
#include<bits/stdc++.h> using namespace std; int t,pow2[15]; int a,b; int len,num[10]; int f[10][4600]; void get_fa(int &a){ int x=0,cnt=0;; while(a){ x+=pow2[cnt++]*(a%10); a/=10; } a=x; } int dfs(int s,int sum,bool lim){ if(sum<0) return 0; if(!s) return 1; if(!lim&&f[s][sum]!=-1) return f[s][sum]; int mx= lim ? num[s] : 9 ; int ret=0; for(int i=0;i<=mx;i++) ret+=dfs(s-1,sum-i*pow2[s-1],lim&&i==mx); if(!lim) f[s][sum]=ret; return ret; } int cx(int x){ len=0; while(x){ num[++len]=x%10; x/=10; } return dfs(len,a,true); } void nice(int i){ scanf("%d%d",&a,&b); get_fa(a); //printf("%d ",a); printf("Case #%d: %d ",i,cx(b)); } int main(){ pow2[0]=1; for(int i=1;i<=10;i++) pow2[i]=pow2[i-1]*2; memset(f,-1,sizeof(f)); scanf("%d",&t); for(int i=1;i<=t;i++) nice(i); }