1 条题解
-
0
自动搬运
来自洛谷,原作者为

BitByBit
a.k.a. 海绵猴子搬运于
2025-08-24 21:37:25,当前版本为作者最后更新于2025-03-22 08:33:54,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意
给你一个电路,电路中的元件有一个损坏的概率,求整个电路断路的概率。
分析
令 为整个电路断路的概率, 分别为 断路的概率。
如图,对于一个串联的电路, 和 中只要有一个损坏了,整个电路就断路了。所以只有两个元件都不损坏才能使整个电路不损坏。所以根据乘法原理 。
同理,对于并联电路,只有两个原件断路,整个电路才断路。所以 。于是就把题目变成了表达式求值。
首先应匹配括号。用一个栈,每次遇到左括号就压入,遇到右括号就让栈顶括号匹配当前括号。
#define ll long long ... stack<ll>q; ... for(ll i=1;i<=m;i++) if(s[i]=='(')q.push(i); else if(s[i]==')') { f[q.top()]=i; q.pop(); }然后分治处理表达式。
double dfs(ll x,ll y)//处理s[x..y] { if(f[x]==y)//如果x和y匹配就把括号去掉 { x++;y--; } if(x==y&&isalpha(s[x]))return a[s[x]-64]; //如果只有一个元件就返回其损坏概率 ll k=0; for(ll i=x;i<=y;i++) { if(s[i]=='(')k++; else if(s[i]==')')k--; if(k==0&&s[i]==',')return 1-(1-dfs(x,i-1))*(1-dfs(i+1,y)); //找到串联的地方,分治解决两边 } for(ll i=x;i<=y;i++) { if(s[i]=='(')k++; else if(s[i]==')')k--; if(k==0&&s[i]==')'&&s[i+1]=='('&&i!=y)return dfs(x+1,i-1)*dfs(i+1,y); //找并联的地方 } return 1; }所求就是
dfs(1,n)。完整程序
#include<bits/stdc++.h> #define ll long long using namespace std; const ll N=100010; ll n,m; ll f[N]; double a[N]; string s; stack<ll>q; double dfs(ll x,ll y) { if(f[x]==y) { x++;y--; } if(x==y&&isalpha(s[x]))return a[s[x]-64]; ll k=0; for(ll i=x;i<=y;i++) { if(s[i]=='(')k++; else if(s[i]==')')k--; if(k==0&&s[i]==',')return 1-(1-dfs(x,i-1))*(1-dfs(i+1,y)); } for(ll i=x;i<=y;i++) { if(s[i]=='(')k++; else if(s[i]==')')k--; if(k==0&&s[i]==')'&&s[i+1]=='('&&i!=y)return dfs(x+1,i-1)*dfs(i+1,y); } return 1; } int main() { scanf("%lld",&n); cin>>s; s=" "+s; m=s.size()-1; for(ll i=1;i<=n;i++) scanf("%lf",&a[i]); for(ll i=1;i<=m;i++) if(s[i]=='(')q.push(i); else if(s[i]==')') { f[q.top()]=i; q.pop(); } printf("%.4f",dfs(1,m)); }
- 1
信息
- ID
- 1438
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者