思路差不多,判断连续3次出现的方式不一样,为何只有30分?
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5+100;
const double eps=1e-8;
const double pi=acos(-1);
int f[13][5][2][2][10],num[13];
//ctn表示某个数连续出现了多少次,last表示上一个数是什么
int dfs(int pos,int limit,int eight,int four,int ctn,int last)
{
if(eight&&four) return 0;
if(pos==0) return ctn==3;
if(!limit&&f[pos][ctn][eight][four][last]!=-1) return f[pos][ctn][eight][four][last];
int up=limit?num[pos]:9,res=0;
for(int i=0;i<=up;i++)
{
//if(i==8&&four||i==four&&eight) return 0;
if(ctn==3) res+=dfs(pos-1,limit&&(i==up),eight||i==8,four||i==4,3,i);
else res+=dfs(pos-1,limit&&(i==up),eight||i==8,four||i==4,i==last?ctn+1:1,i);
}
if(!limit) f[pos][ctn][eight][four][last]=res;
return res;
}
int sol(int x)
{
int len=0,res=0;
while(x) num[++len]=x%10,x/=10;
if(len!=11) return 0;
for(int i=1;i<=num[len];i++)
{
res+=dfs(len-1,i==num[len],i==8,i==4,1,-1);
}
return res;
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int l,r;
memset(f,-1,sizeof(f));
cin>>l>>r;
int ans=sol(r)-sol(l-1);
cout<<ans<<endl;
return 0;
}
//