疑问玄关
查看原帖
疑问玄关
766436
Mr_RedStone楼主2025/1/5 13:30

两种代码。

这种是第一层搜索直接跳过有前导零的情况。可以过。

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);
}
2025/1/5 13:30
加载中...