传送门:嘿原题在这
注释写的很详细啦
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dp[10][2],a[10];
int l,r,tot;
//pos表示当前位置,pre表示前一个数,sta表示当前的状态,也就是之前是否为6,lim表示当前是否
//是有限制的,就比如说967当我第一个数选择9时第二个数只能选择0~6了,这种情况需要标记其他情况都是0~9
int dfs(int pos,int pre,int sta,int lim)
{
int cur=0;
if (pos==0) return 1;//如果执行到0了,当前构成的数可行
if (!lim&&dp[pos][sta]!=-1) return dp[pos][sta];
int up=lim?a[pos]:9;
for (int i=0;i<=up;i++)
{
//排除不可能情况
if (i==4) continue;
if (pre==6&&i==2) continue;
cur+=dfs(pos-1,i,i==6,lim&&i==a[pos]);
}
if(!lim) dp[pos][sta]=cur;
return cur;
}
int solve(int x)
{
tot=0;
while(x)
{
a[++tot]=x%10;
x/=10;
}
return dfs(tot,-1,0,1);
}
int main()
{
while(~scanf("%d%d",&l,&r)&&(l+r))
{
memset(dp,-1,sizeof(dp));
printf("%d\n",solve(r)-solve(l-1));
}
return 0;
}