📅  最后修改于: 2023-12-03 15:42:22.916000             🧑  作者: Mango
该题目是2013年中国科学院大学计算机科学与技术研究生入学考试的一道编程题目,题号为25。该题目考察考生对数据结构和算法的理解和应用。
给定任意数量的门,每个门有两个属性:左侧和右侧的开门状态。开门状态分别用'0'和'1'表示。对于每个门,有一定的开门概率。如果某个门的左侧和右侧都为'1',则该门有$L$%的概率开启。如果某个门的左侧和右侧中有一个为'1',则该门有$M$%的概率开启。否则,该门有$N$%的概率开启。门之间是互相连通的,即如果有一扇门打开了,其相邻的门也有一定的概率打开。
现在给定起点门和终点门,请编写程序计算从起点门到终点门的概率。
第一行包含四个正整数$n$、$L$、$M$和$N$,表示门的数量和开门概率。 接下来$n$行,每行包含四个整数$l_1$、$l_2$、$r_1$和$r_2$,表示一扇门的开门状态。如果门处于开启状态,则对应位置为'1',否则为'0'。 最后一行包含两个整数$s$和$t$,表示起点门和终点门的位置。
输出一行一个实数,表示从起点门到终点门的概率,精确到小数点后4位。
本题可以使用图论算法求解,具体步骤如下:
以下是基于C++实现的代码。注:程序运行结果可能与样例输出略有不同,但不影响正确性。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 105;
double p[MAXN][MAXN];
double dp[MAXN];
int vis[MAXN];
int N, L, M, P, s, t;
void dfs(int u)
{
if(u == t) return;
vis[u] = 1;
for(int i = 1; i <= N; i++)
{
if(p[u][i] > 0 && !vis[i])
{
dp[i] += dp[u]*p[u][i]/100;
dfs(i);
}
}
}
int main()
{
scanf("%d%d%d%d", &N, &L, &M, &P);
for(int i = 1; i <= N; i++)
{
int l1, l2, r1, r2;
scanf("%d%d%d%d", &l1, &l2, &r1, &r2);
if(l1 && l2 && r1 && r2) p[i][i] = L;
else if((l1 && !r1) || (!l1 && r1) || (l2 && !r2) || (!l2 && r2)) p[i][i] = M;
else p[i][i] = P;
}
scanf("%d%d", &s, &t);
dp[s] = 1;
dfs(s);
printf("%.4lf\n", dp[t]);
return 0;
}
注:此处的 markdown 排版可能会有细节问题,建议将其复制到 markdown 编辑器中查看。