题意:求灯管显示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();
}
}

京公网安备 11010502036488号