两种代码。
这种是第一层搜索直接跳过有前导零的情况。可以过。
long long dfs(int step,bool flag,int l1,int l2,bool f8,bool f4,bool con){
if(f8&&f4) return 0;
if(step<1) return con;
if(!flag&&f[step][l1][l2][f8][f4][con]!=-1) return f[step][l1][l2][f8][f4][con];
long long cnt=0;
int up=flag?a[step]:9;
for(int i=0;i<=up;i++){
cnt+=dfs(step-1,flag&&(i==up),i,l1,f8||(i==8),f4||(i==4),con||(i==l1&&i==l2));
}
if(!flag) f[step][l1][l2][f8][f4][con]=cnt;
return cnt;
}
long long solve(long long x){
memset(f,-1,sizeof(f));
int sz=0;
while(x){
a[++sz]=x%10;
x/=10;
}
if(sz!=11) return 0;
long long ret=0;
for(int i=1;i<=a[sz];i++){
ret+=dfs(sz-1,i==a[sz],i,0,i==8,i==4,0);
}
return ret;
}
这样的过不了,这样的是添加了一个 lead 标记表示是否含有前导零,lead = 1 表示有前导零,然后直接从第一层开始搜。过不了。
long long dfs(int step,bool flag,bool lead,int l1,int l2,bool f8,bool f4,bool con){
if(f8&&f4) return 0;
if(step<1) return con;
if(!flag&&!lead&&f[step][l1][l2][f8][f4][con]!=-1) return f[step][l1][l2][f8][f4][con];
long long cnt=0;
int up=flag?a[step]:9;
for(int i=0;i<=up;i++){
cnt+=dfs(step-1,flag&&(i==up),lead&&(i==0),i,l1,f8||(i==8),f4||(i==4),con||(!lead&&i==l1&&i==l2));
}
if(!flag&&!lead) f[step][l1][l2][f8][f4][con]=cnt;
return cnt;
}
long long solve(long long x){
memset(f,-1,sizeof(f));
int sz=0;
while(x){
a[++sz]=x%10;
x/=10;
}
if(sz!=11) return 0;
return dfs(sz,1,1,0,0,0,0,0);
}