题目大意

8个相同的故障七段数码管,每个灯管i有pi%的概率被点亮,各灯管独立。把 8 个分成两排,每排 4 个,分别拼成四位数 A 和 B。 要求: 每个显示器至少有一个灯管被点亮(不能全灭); 每个显示器显示的数字是 0~9 中的合法数字; 最终 A+B=C。 求满足所有条件的概率,结果以分数模 998244353 形式输出

核心思路

灯管状态是固定的,因此可以根据组成每个数的灯管的状态来求出某个合法数字的出现概率。

x数组表示单个显示器的概率建模 p数组表示每个数字的出现概率 t数组表示四位数的概率,一排4个显示器拼成一个四位数x(允许前导0)其概率为:t[X]=p[X1​]×p[X2​]×p[X3​]×p[X4​] 其中 X1​,X2​,X3​,X4​ 分别是 X 的个位、十位、百位、千位数字。

接着求出两排相加等于C的总概率 我们需要A+B=C其中A,B都是0~2026之间的四位数(因为 C≤2026)。 总概率就是所有满足 A+B=C 的配对概率之和

#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'
const int mod=998244353;
const int N = 500010;
int a[10];
int p[10];
int t[2500];
int x[10][7]={
	{1,1,1,0,1,1,1},
	{0,0,1,0,0,1,0},
	{1,0,1,1,1,0,1},
	{1,0,1,1,0,1,1},
	{0,1,1,1,0,1,0},
	{1,1,0,1,0,1,1},
	{1,1,0,1,1,1,1},
	{1,0,1,0,0,1,0},
	{1,1,1,1,1,1,1},
	{1,1,1,1,0,1,1}
};
int fpow(int a,int b){
	a%=mod;
	int r=1;
	while(b){
		if(b&1){
			r=r*a%mod;
		}
		a=a*a%mod;
		b>>=1;
	}
	return r;
}
void solve(){
	int c;
	cin>>c;
	int inv1=fpow(100,mod-2);
	for(int i=1;i<=7;i++){
		cin>>a[i];
		a[i]=a[i]*inv1%mod;
	}
	for(int i=0;i<10;i++){
		int tmp=1;
		for(int j=1;j<=7;j++){
			if(x[i][j-1]){
				tmp=tmp*a[j]%mod;
			}else{
				tmp=tmp*((1-a[j]+mod)%mod)%mod;
			}
		}
		p[i]=tmp;
	}
	int x1,x2,x3,x4;
	for(int i=0;i<=2026;i++){
		x1=i%10;
		x2=(i/10)%10;
		x3=(i/100)%10;
		x4=i/1000;
		t[i]=p[x1]*p[x2]%mod*p[x3]%mod*p[x4]%mod;
	}
	
	int sum=0;
	for(int ma=0;ma<=c;ma++){
		int mb=c-ma;
		if(mb>=0){
			sum+=t[ma]*t[mb]%mod;
			sum%=mod;	
		}
	}
	cout<<sum<<endl;
}

signed main(){
	ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
	int T=1;cin>>T;
	while(T--){
		solve();
	}
	return 0;
}