可以用数位DP,也可以暴力打表,两种都可以。
状态:dp[i,j]表示枚举到第i位时,前一位(即i+1位)的数字为j时的方案数。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
ll dp[10][20];
int digit[20];
ll dfs(int pos,int pre,bool limit,bool lead)
{
if(pos==-1) return 1; //相当于边界
if(!limit&&!lead&&dp[pos][pre]!=-1) return dp[pos][pre];
ll ret=0;
int up= limit? digit[pos]:9;
for(int i=0;i<=up;++i)
{
int p=i;
if(!i&&lead) p=-inf;
if(i==4) continue; //相当于状态转移
if(pre==6&&i==2) continue; //相当于状态转移
ret+=dfs(pos-1,p,limit&&i==digit[pos],p==-inf);
}
if(!lead&&!limit) dp[pos][pre]=ret;
return ret;
}
ll solve(ll n)
{
int pos=0;
while(n)
{
digit[pos++]=n%10;
n/=10;
}
return dfs(--pos,-inf,1,1);
}
int main()
{
ll a,b;
while(cin>>a>>b)
{
if(!a&&!b) break;
if(a>b) swap(a,b);
memset(dp,-1,sizeof(dp));
cout<<solve(b)-solve(a-1)<<endl;
}
return 0;
}