这道题直接暴力+打表就可以过,也是一道数位DP入门题
//暴力打表
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
const int N=1000000+10;
int ans[N];
bool is_laoer(int n)
{
while(n)
{
if(n%10==4) return 0;
if(n%10==2&&n/10%10==6) return 0;
n/=10;
}
return 1;
}
int main()
{
ans[0]=0;
for(int i=1;i<N;i++)
ans[i]=ans[i-1]+is_laoer(i);
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0) break;
printf("%d\n",ans[m]-ans[n-1]);
}
return 0;
}
//数位DP
d[len][k](k为0或1)表示长度为len+1,开头是否为6(看k)的数到1之间有多少个符合条件的数(不含4和62)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=10;
int d[N][2];
int dis[N];
int dp(int len,int num,bool flag)
{
if(len==-1) return 1;
if(!flag&&d[len][num]!=-1) return d[len][num];
int ans=0;
int end=flag?dis[len]:9;
for(int i=0;i<=end;i++)
{
if(i==4||num&&i==2) continue;
ans+=dp(len-1,i==6,flag&&i==end);
}
if(!flag) d[len][num]=ans;
return ans;
}
int solve(int n)
{
int t=0;
while(n)
{
dis[t++]=n%10;
n/=10;
}
int ans=0;
return dp(t-1,0,true);
}
int main()
{
memset(d,-1,sizeof(d));
int l,r;
while(~scanf("%d%d",&l,&r))
{
if(l==0&&r==0) break;
printf("%d\n",solve(r)-solve(l-1));
}
return 0;
}