JZOJ 4.1 C组 【GDOI2005】电路稳定性

Description

  你有一个电路,电路上有n个元件。已知元件i损坏而断开的概率是Pi(i=1,2….n,0<=pi<=1)。
  请你算出整个电路断路的概率。
  元件的连接方式很简单,对电路的表示:
  1. 一个元件是最小的电路,用A表示元件1,B表示元件2,如此类推。
  2. K个电路组成的串联电路表示为:电路1,电路2,。。。。,电路K。
  3. K个电路组成的并联电路表示为:(电路1)(电路2)。。。(电路K)。

Input

  第一行是一个整数n(1<=n<=26),表示一共有多少个元件,第二行是表示电路的字符串,最后是n行,每行是一个实数Pi(i=1,2,…,n,0<=Pi<=1),表示该元件断路的概率。

Output

  输出一个实数,表示整个电路断路的概率,精确到小数点后4位。

Sample Input

5
(A,B)((C)(D),E)
0.2
0.3
0.4
0.5
0.6

Sample Output

0.2992


求串联断电的公式为1-(1-x)*(1-y)
并联为x*y
有了这两个公式,就可以开始我们神奇而漫长的模拟之旅了
一个for先枚举他的长度,
如果为字母则将这个字母替换为实数;
如果搜到了右括号,将向前枚举左括号:如果搜到了逗号,就将串联的断电的概率求出来。
最后在将枚举到的左括号的前后两个的并联的断电概率求出来。


代码如下:

var
        c:char;s:ansistring;
        a:array[1..26]of real;
        num:array[0..1000]of real;
        z,q:array[0..1000]of longint;
        p:array[0..1000]of char;
        i,j,k,v,l,n,m,len:longint;
        ans,x,y:real;

procedure main;
begin
  for i:=1 to l do
    begin
      c:=s[i];
      if ('A'<=c)and('Z'>=c) then
        begin
          k:=ord(c)-64;
          inc(m);
          num[m]:=a[k];
          z[m]:=i;
        end
      else
        if (c=')') then
          begin
            while (p[len]<>'(') do
              begin
                if (p[len]=',') then
                  begin
                    x:=num[m];
                    dec(m);
                    y:=num[m];
                    num[m]:=1-(1-x)*(1-y);
                    dec(len);
                  end;
              end;
              dec(len);
              if (z[m-1]>q[len]) then
                begin
                  x:=num[m];dec(m);
                  y:=num[m];
                  num[m]:=x*y;
                end;
          end
        else
          begin
            inc(len);
            p[len]:=c;
            q[len]:=i;
          end;
    end;
end;

procedure init;
begin
  readln(n);
  readln(s);
  for i:=1 to n do read(a[i]);
  s:='('+s+')';
  l:=length(s);
  len:=0;
  m:=0;
end;

begin
  init;
  main;
  writeln(num[m]:0:4);
end.
原文地址:https://www.cnblogs.com/Comfortable/p/8412344.html