很水的一道题但我还是要发出来 因为我学会了用记忆化搜索写数位dp的简单题
题目链接:点击打开链接
#include<stdio.h>
#include<string.h>
int digit[15];
int l;
int dp[15][2];//dp[i][j]表示长度为i位(前缀(第i+1位)为6,前缀不为6)所有符合要求的数的个数
int dfs(int pos,int pre,int doing)//pos当前位置,pre前缀的状态(是不是6),doing为1表示当前枚举的不是自由位(不能枚举0-9,而应给枚举0-digit[pos])
{
if(pos==-1)return 1;
if(!doing&&dp[pos][pre]!=-1)return dp[pos][pre];
int i,End,ans=0;
End=doing?digit[pos]:9;//判断当前是否是自由位
for(i=0;i<=End;i++)
{
if(pre&&i==2)//上一位是6,当前为是2为非法状态
{
continue;
}
else if(i==4)
{
continue;
}
ans+=dfs(pos-1,i==6,doing&& i==End);
}
if(!doing)//如果当前是在枚举自由位就把答案储存下来
dp[pos][pre]=ans;
return ans;
}
int solve(int x)
{
memset(dp,-1,sizeof(dp));//
l=0;
memset(digit,0,sizeof(digit));//这两个初始化必须得加 不然就错了 我也不知道为什么
while(x>0)
{
digit[l++]=x%10;
x=x/10;
}
return dfs(l,0,1);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m),(n+m))
{
printf("%d\n",solve(m)-solve(n-1));
}
return 0;
}