P1310 表达式的值

这道题看到时很懵逼,先码了一个表达式求值:

var i,j,k:longint;
    s:ansistring;
    num:array[-1..1000000]of longint;//栈
    fh:array[-1..1000000]of char;//栈
    ch:char;
    f:array[char]of longint;
    m,n,t,h:longint;
    x,y:longint;
function js(m,n:longint;ch:char):longint;
begin
  if ch='+' then exit((m+n) mod 10000);
  if ch='*' then exit((m*n) mod 10000);
end;
begin
  readln(s);
  f['(']:=1;//优先级
  f[')']:=1;
  f['*']:=3;
  f['+']:=2;
  t:=0;//数字栈栈顶
  h:=0;//符号栈栈顶
  i:=0;
  s:='('+s+')';
  while i<length(s) do//枚举
  begin
  inc(i);
    if s[i]in ['0'..'9'] then//数字入栈
    begin
      inc(t);
      num[t]:=ord(s[i])-48;
      inc(i);
      while s[i] in ['0'..'9'] do//字符串转数字
      begin
      num[t]:=(num[t]*10+ord(s[i])-48) mod 10000;
      inc(i);
      end;
    end;
    begin
      if s[i] in ['+','*','('] then//运算符入栈
      begin
        if (s[i] in ['+','*']) and (f[fh[h]]>=f[s[i]]) then//判断优先级
        begin
          num[t-1]:=js(num[t-1],num[t],fh[h]);//计算
          dec(t);
          dec(h);
        end;
        inc(h);
        fh[h]:=s[i];
      end else
      if s[i]=')' then//括号
      begin
        while (fh[h]<>'(') and (h>=0) and (t<>0) do
        begin
          num[t-1]:=js(num[t-1],num[t],fh[h]);//计算
          dec(t);
          dec(h);
        end;
        dec(h);
      end;
    end;
  end;
  write(num[1] mod 10000);//答案在[1]中
end.

但接下来怎么办就不知道了。
经过一晚上的深思熟虑,终于想出表算

type xx=record//记录每个值中0,1出现的个数
        x0:longint;
        x1:longint
        end;
var i,j,k:longint;
    s,u,p:ansistring;
    num:array[-1..1000000]of xx;
    fh:array[-1..1000000]of char;
    ch:char;
    f:array[char]of longint;
    m,n,t,h:longint;
    x,y:longint;
function js(m,n:xx;ch:char):xx;//利用乘法原理和加法原理
begin
  if ch='+' then
  begin
    js.x1:=(m.x1*n.x1+m.x0*n.x1+m.x1*n.x0) mod 10007;
    js.x0:=(n.x0*m.x0) mod 10007;
  end;
  if ch='*' then
  begin
    js.x1:=(m.x1*n.x1) mod 10007;
    js.x0:=(m.x0*n.x0+m.x0*n.x1+m.x1*n.x0) mod 10007;
  end;
  exit(js);
end;
begin//貌似其他都一样...
  readln(p);
  readln(u);
  s:='(';
  u:='('+u+')';
  for i:=2 to length(u)-1 do
  begin
  if (u[i] in ['+','*',')'])  and (u[i-1]<>')') then s:=s+'.';
  s:=s+u[i];
  end;
  if s[length(s)] in ['+','*'] then s:=s+'.';
  s:=s+')';
  f['(']:=1;
  f[')']:=1;
  f['*']:=3;
  f['+']:=2;
  t:=0;
  h:=0;
  i:=0;
  while i<length(s) do
  begin
  inc(i);
    if s[i]='.' then
    begin
      inc(t);
      num[t].x1:=1;
      num[t].x0:=1;
    end;
    begin
      if s[i] in ['+','*','('] then
      begin
        if (s[i] in ['+','*']) and (f[fh[h]]>=f[s[i]]) then
        begin
          num[t-1]:=js(num[t-1],num[t],fh[h]);
          dec(t);
          dec(h);
        end;
        inc(h);
        fh[h]:=s[i];
      end else
      if s[i]=')' then
      begin
        while (fh[h]<>'(') and (h>=0) and (t<>0) do
        begin
          num[t-1]:=js(num[t-1],num[t],fh[h]);
          dec(t);
          dec(h);
        end;
        dec(h);
      end;
    end;
  end;
  write(num[1].x0 mod 10007);
end.

栈的运用在普及组很重要,初赛也时常出现,要多加重视!!!

猜你喜欢

转载自blog.csdn.net/sxy__orz/article/details/85254682