P8804 [蓝桥杯 2022 国 B] 故障
题目描述
在软件或系统开发中,我们会遇到各种各样的故障。为了从故障现象反推故障原因,工程师们会总结一种叫做相关性矩阵的二维表格,来表示故障原因与故障现象之间的关系。比如:

其中每行表示一种故障原因,每一列表示一种故障现象。该矩阵表示故障原因 AAA 可能产生故障现象 222、333、444,故障原因 BBB 可能产生故障现象 111、333。
在实际开发过程中,如果出现了故障原因,工程师就可以根据故障现象,去计算每种故障原因产生的概率,并按照概率大小对故障原因进行排查,以达到快速定位故障原因的目的。
现在,我们假设系统开发中同一时间只会出现一种故障原因, 并且故障原 因引起各故障现象是独立事件。举个例子来说:
假设系统现在发生了故障原因 AAA, 有 13frac{1}{3}31 的概率出现故障现象 222,有 14frac{1}{4}41 的概率出现故障现象 333,有 12frac{1}{2}21 的概率出现故障现象 444。由于 333 种现象是独立发生的,因此有 12×3×4frac{1}{2 times 3 times 4}2×3×41 的概率同时出现故障 222、333、444。
约定若相关性矩阵中没有 x 记号, 则表示该故障原因一定不会产生某故障现象,比如故障原因 AAA,一定不会产生故障现象 111。根据历史经验数据,我们统计得到了每一种故障原因出现的概率以及每一种故障原因对应的故障现象产生概率。
现在已知系统出现的故障现象,求问各个故障原因发生的概率。
输入格式
第 111 行:222 个正整数 N,M,NN, M, NN,M,N 表示故障原因的个数(编号 1…N),M1 ldots N),M1…N),M 表示故障现象的个数(编号 1…M1 ldots M1…M)。
第 222 行: NNN 个整数,第 iii 个数表示故障原因 iii 产生的概率 PiP_{i}Pi。
第 3…N+23 ldots N+23…N+2 行:每行 MMM 个整数,第 i+2i+2i+2 行第 jjj 个整数 PijP_{i j}Pij 表示故障原因 iii 出现故障现象 jjj 的概率(百分比)。
第 N+3N+3N+3 行:111 个正整数 KKK,表示目前出现的故障现象数量。
第 N+4N+4N+4 行:KKK 个正整数,依次为当前出现的故障现象编号,不会重复。
输出格式
第 1…N1 ldots N1…N 行:按概率从高到低输出每种故障原因及其可能的概率,若出现 概率相同则优先输出编号小的故障原因。第 111 个数为故障原因编号, 第 222 个数为故障概率(百分比),保留 222 位小数。
输入输出样例 #1
输入 #1
3 5
30 20 50
0 50 33 25 0
30 0 35 0 0
0 0 0 25 60
1
3
输出 #1
2 56.89
1 43.11
3 0.00
说明/提示
对于所有测试用例,1≤N≤40,1≤M≤20,0≤Pi≤100,∑(Pi)=1001 leq N leq 40,1 leq M leq 20,0 leq P_{i} leq 100, sumleft(P_{i}right)=1001≤N≤40,1≤M≤20,0≤Pi≤100,∑(Pi)=100, 0≤Pij≤1000 leq P_{i j} leq 1000≤Pij≤100。
蓝桥杯 2022 国赛 B 组 G 题。
C++实现
#include
using namespace std;
const int maxn=500;
double a[maxn],b[maxn][maxn],dp[maxn];
int N,M,K,c[maxn];
struct bro{
int id;double p;
}d[maxn];
bool cmp(bro x,bro y){
if(fabs(x.p-y.p)1e-6)return x.idy.id;//防止精度丢失
return x.p>y.p;
}
int main(){
cin>>N>>M;
int i,j,k;
double sum=0;//当前故障原因发生并且产生出现的现象的概率
for(i=1;iN;i++){
cin>>a[i];
a[i]*=0.01;//百分比还原成小数
}
for(i=1;iN;i++)
for(j=1;jM;j++){
cin>>b[i][j];
b[i][j]=b[i][j]*0.01;//百分比还原成小数
}
cin>>K;
for(i=1;iK;i++){
cin>>k;
c[k]=1;//这个现象发生了
}
for(i=1;iN;i++){//i故障发生并且导致出现当前现象的概率
dp[i]=a[i];
for(j=1;jM;j++){
if(c[j])dp[i]=dp[i]*b[i][j];
else dp[i]=dp[i]*(1-b[i][j]);
}
}
for(i=1;iN;i++)sum+=dp[i];//发生当前现象的总概率
for(i=1;iN;i++){
d[i].id=i;//记录故障编号
d[i].p=dp[i]*100.0/sum;//计算故障概率
}
sort(d+1,d+N+1,cmp);
for(i=1;iN;i++)printf("%d %.2lfn",d[i].id,d[i].p);
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
文章来源于互联网:打卡信奥刷题(1785)用C++实现信奥 P8804 [蓝桥杯 2022 国 B] 故障
注意事项1.在撰写书评时,可以给 AI设定一个相关性较高的身份角色,会提升它回答的质量。2.AI目前还无法获取整本书的信息,所以需要创作者提供给它。图书内容越详细越好。3.提供作者名的时候,如果是国外作者,建议使用其英文名4.因为 AI目前还无法获取整本书的信…
5bei.cn大模型教程网










