题意:求灯管显示A+B=N的概率

知识点:数学

思路:

根据给你的每个灯管亮灯的概率求出每个数字出现的概率,然后再根据每个数字的概率枚举出每一对A+B=N的概率。其中分数取模可以用快速幂在计算完全部ans后统一计算(56个灯管);

参考代码:

using namespace std;
#define int long long 
const int mod=998244353;
vector<vector<int>> num= {
	{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 qk(int a,int b) {
	  int res=1;
	  a=a%mod;
    while(b>0){
        if(b&1) res=(res*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return res;
}
void slove(){
	int c;cin>>c;
	vector<int> p(8);
	for(int i=0;i<=6;i++) cin>>p[i];
	//当前概率下每一个数字被点亮的概率 
	vector<int> now_p(10,1);
	for(int i=0;i<10;i++) {
		for(int j=0;j<=6;j++) {
			if(num[i][j]) 
				now_p[i]=(now_p[i]*p[j])%mod;
			else 
				now_p[i]=(now_p[i]*(100-p[j]))%mod;
		}
	}
	//计算概率
	int a,b,ans=0;
	int q_a,b_a,s_a,g_a;
	int q_b,b_b,s_b,g_b;
	for(int i=0;i<=c;i++) {
		q_a=now_p[i/1000]%mod;
		b_a=now_p[i/100%10]%mod;
		s_a=now_p[i/10%10]%mod;
		g_a=now_p[i%10]%mod;
		a=((((q_a*b_a)%mod)*s_a)%mod*g_a)%mod;
		int j=c-i;
		q_b=now_p[j/1000]%mod;
		b_b=now_p[j/100%10]%mod;
		s_b=now_p[j/10%10]%mod;
		g_b=now_p[j%10]%mod;
		b=((((q_b*b_b)%mod)*s_b)%mod*g_b)%mod;
		ans=(ans+a*b%mod)%mod;
	}
	ans=ans*qk(qk(100,56),mod-2)%mod;
	cout<<ans<<endl;
}
signed main() {
	int t;cin>>t;
	while(t--) {
		slove();
	}
}