题目:点击打开链接
题意:即“不要49”
#include<stdio.h>
#include<string.h>
bool prev, flag;
int now, len; //标记note记忆化搜索49位数
int numb[30]; //存储数字
long long note[30][2];
long long dfs(int now, bool prev, bool flag){
if(now == len) return 1; //记忆化搜索
if(flag == false){
if(prev == true && ~note[now][1]) return note[now][1];
if(prev == false && ~note[now][0]) return note[now][0];
}
int bound = 9;
if(flag) bound = numb[now + 1]; //如果当前位数到边界下一位数范围存在约束(0~numb[now + 1])否则范围无约束(即0~9)
long long ret = 0;
for(int i = 0; i <= bound; i++){
if(prev == true && i == 9) continue; //不要49
ret += dfs(now + 1, i == 4, flag == true && i == bound);
}
if(flag == false){
if(prev == true)
return note[now][1] = ret;
return note[now][0] = ret;
}
return ret;
}
int main(){
int k, T;
long long na, sum, n;
char a[30], b[30];
scanf("%d", &T);
while(T--){
scanf("%I64d", &na);
sprintf(a, "%I64d", na);
n = 0;
len = strlen(a);
for(int i = 0; i < len; i++) numb[i + 1] = a[i] - '0';
memset(note, -1, sizeof(note));
n = dfs(0, false, true); //计算0~na之间的无49的数的个数
sum = na - n + 1; //sum即1~na之间有49的数的个数
printf("%I64d\n", sum);
}
return 0;
}