一道简单的数位dp题,想法和我做的loj10166差不多。
dfs中
l
l
表示位数,表示前一位是否为
6
6
,表示是否前几位都取到最大。
#include<bits/stdc++.h>
#define il inline
using namespace std;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
il int read(){
int x=0,f=1;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=(x+(x<<2)<<1)+c-48;
return x*f;
}
char sr[1<<21],z[20];int C=-1,Z;
il void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
il void print(int x){
if(C>1<<20)Ot();
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
int n,m,f[8][2],c[8];
il int dfs(int l,bool sx,bool o){
if(!l) return 1;
if(!o&&f[l][sx]!=-1) return f[l][sx];
int res=0,r=o?c[l]:9;
for(int i=0;i<=r;++i){
if(i==4||sx&&i==2) continue;
res+=dfs(l-1,i==6,o&&i==r);
}
if(!o) f[l][sx]=res;
return res;
}
il int calc(int x){
int l=0;
while(x){c[++l]=x%10;x/=10;}
return dfs(l,0,1);
}
int main(){
memset(f,-1,sizeof(f));
n=read(),m=read();
while(m){
print(calc(m)-calc(n-1));
n=read(),m=read();
}Ot();
return 0;
}