搜索大法好
代码比较清楚就不细讲了,为了避免前导零,我们直接枚举第一位就行了
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lli long long int
using namespace std;
lli num[12];
lli f[11][11][11][2][2][2][2];
inline lli dfs(int p,int l1,int l2,bool can,bool jud,bool l4,bool l8)
{
//l1倒数第二位,l2倒数第一位,can之前有没有连续的三个相同数字,l4->4出没出现过,l8同理
if(l4&&l8) return 0;
if(p<=0) return can;
if (f[p][l1][l2][can][jud][l4][l8]!=-1) return f[p][l1][l2][can][jud][l4][l8];
lli emm=!jud?num[p]:9,ans=0;
for(int i=0;i<=emm;i++)
ans+=dfs(p-1,i,l1,can||(i==l2&&i==l1),jud||(i<emm),l4||(i==4),l8||(i==8));
return f[p][l1][l2][can][jud][l4][l8]=ans;
}
inline void slove(lli x,lli y)
{
lli len=0,ans=0;
memset(f,-1,sizeof(f));
while(x) num[++len]=x%10,x/=10;
for(int i=1;i<=num[len];i++)
ans+=dfs(len-1,i,0,0,i<num[len],i==4,i==8);
if (len<11) ans=0;
lli lon=0,que=0;
memset(f,-1,sizeof(f));
while(y) num[++lon]=y%10,y/=10;
for(int i=1;i<=num[lon];i++)
que+=dfs(lon-1,i,0,0,i<num[lon],i==4,i==8);
if (lon<11) que=0;
cout<<que-ans;
return ;
}
signed main()
{
lli l,r;cin>>l>>r;slove(l-1,r);
return 0;
}