zoukankan      html  css  js  c++  java
  • 等价表达式 (codevs 1107)题解

    【问题描述】

    明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。

    这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?

    这个选择题中的每个表达式都满足下面的性质:
    1.表达式只可能包含一个变量‘a’。
    2.表达式中出现的数都是正整数,而且都小于10000。
    3.表达式中可以包括四种运算‘+’(加),‘-’(减),‘*’(乘),‘^’(乘幂),以及小括号‘(’,‘)’。小括号的优先级最高,其次是‘^’,然后是‘*’,最后是‘+’和‘-’。‘+’和‘-’的优先级是相同的。相同优先级的运算从左到右进行。(注意:运算符‘+’,‘-’,‘*’,‘^’以及小括号‘(’,‘)’都是英文字符)
    4.幂指数只可能是1到10之间的正整数(包括1和10)。
    5.表达式内部,头部或者尾部都可能有一些多余的空格。
    下面是一些合理的表达式的例子:
    ((a^1)^2)^3,a*a+a-a,((a+a)),9999+(a-a)*a,1+(a-1)^3,1^10^9……

    【样例输入】

         (a+1)^2
         3
         (a-1)^2+4*a
         a+1+a
         a^2+2*a*1+1^2+10-10+a-a

    【样例输出】

         AC

    【解题思路】

         本题为NOIP2005提高组第四题,求两个表达式是否等价,其实就是看两个表达式的值是否相等,因此,我们将a换为随机化的数,多次随机化的数产生的结果都相等的话,就说明两个表达式等价,便输出表达式的选项,求表达式的值,自然就是用栈来解决,详见NOIP2013普及组第二题。我在这道题上用了两个总过程,一个建栈,一个计算

    【代码实现】

      1 type arr=array[1..2000] of char;
      2      arr2=array[1..2000] of extended;
      3 var ii,jj,n,c1,c2:longint;
      4     tag:boolean;
      5     x1,x2,x3:extended;
      6     c:char;
      7     st,a,e:string;
      8 function pop(var stack:arr; var t:longint):char;
      9 begin
     10  pop:=stack[t];
     11  dec(t);
     12 end;
     13 function top(var stack:arr; var t:longint):char;
     14 begin
     15  top:=stack[t];
     16 end;
     17 procedure push(var stack:arr; ch:char; var t:longint);
     18 begin
     19  inc(t);
     20  stack[t]:=ch;
     21 end;
     22 procedure create(var x,y:string);//建栈
     23 var  s:arr;
     24      tp,i,j,k:longint;
     25 begin
     26  x:=x+'@';i:=1;tp:=0;y:='';
     27  while x[i]<>'@' do
     28   begin
     29    case x[i] of
     30     '0'..'9':
     31      begin
     32       while (x[i]>='0')and(x[i]<='9') do
     33        begin
     34         y:=y+x[i];
     35         inc(i);
     36        end;
     37       dec(i);
     38       y:=y+'.';
     39      end;
     40     'a':y:=y+'a';
     41     '(':push(s,'(',tp);
     42     ')':
     43      begin
     44       if tp>0 then
     45        begin
     46         c:=top(s,tp);
     47         while c<>'(' do
     48          begin
     49           y:=y+c;
     50           c:=pop(s,tp);
     51           if tp>0 then
     52            c:=top(s,tp)
     53           else
     54            break;
     55          end;
     56        end;
     57       if (tp>0)and(c='(')then
     58        c:=pop(s,tp);
     59      end;
     60     '+','-':
     61      begin
     62       if tp>0 then
     63        begin
     64         c:=top(s,tp);
     65         while c<>'(' do
     66          begin
     67           y:=y+c;
     68           c:=pop(s,tp);
     69           if tp>0 then
     70            c:=top(s,tp)
     71           else
     72            break;
     73          end;
     74        end;
     75       push(s,x[i],tp);
     76      end;
     77     '*','/':
     78      begin
     79       if tp>0 then
     80        begin
     81         c:=top(s,tp);
     82         while (c<>'(')and(c<>'+')and(c<>'-') do
     83          begin
     84           y:=y+c;
     85           c:=pop(s,tp);
     86           if tp>0 then
     87            c:=top(s,tp)
     88           else
     89           break;
     90          end;
     91        end;
     92       push(s,x[i],tp);
     93      end;
     94     '^':
     95      begin
     96       if tp>0 then
     97        begin
     98         c:=top(s,tp);
     99         while c='^' do
    100          begin
    101           y:=y+c;
    102           c:=pop(s,tp);
    103           if tp>0 then
    104            c:=top(s,tp)
    105           else
    106            break;
    107          end;
    108        end;
    109       push(s,x[i],tp);
    110      end;
    111     end;
    112    inc(i);
    113   end;
    114  while tp>0 do
    115   y:=y+pop(s,tp);
    116  y:=y+'@';
    117 end;
    118 function pop2(var stack:arr2;var tp:longint):extended;
    119 begin
    120  pop2:=stack[tp];
    121  dec(tp);
    122 end;
    123 function top2(var stack:arr2; var tp:longint):extended;
    124 begin
    125  top2:=stack[tp];
    126 end;
    127 procedure push2(var stack:arr2; num:extended; var tp:longint);
    128 begin
    129  inc(tp);
    130  stack[tp]:=num;
    131 end;
    132 function chu(x,y:extended):extended;
    133 begin
    134  if y=0 then
    135   chu:=-maxlongint
    136  else
    137   chu:=x/y;
    138 end;
    139 function cf(x,y:extended):extended;
    140 var i:longint;
    141 begin
    142  cf:=1;
    143  for i:=1 to round(y) do
    144   cf:=cf*x;
    145 end;
    146 function work(x:string;v:extended):extended;//求表达式的值
    147 var s:arr2;
    148     i,j,tp:longint;
    149     k,w1,w2:extended;
    150 begin
    151  i:=1;tp:=0;
    152  while x[i]<>'@' do
    153   begin
    154    case x[i] of
    155     '0'..'9':
    156      begin
    157       k:=0;
    158       while x[i]<>'.' do
    159        begin
    160         k:=k*10+ord(x[i])-48;
    161         inc(i);
    162        end;
    163       push2(s,k,tp);
    164      end;
    165     'a':
    166      begin
    167       k:=v;
    168       push2(s,k,tp);
    169      end;
    170     '+':push2(s,pop2(s,tp)+pop2(s,tp),tp);
    171     '-':
    172      begin
    173       w2:=pop2(s,tp);
    174       w1:=pop2(s,tp);
    175       push2(s,w1-w2,tp);
    176      end;
    177     '*':push2(s,pop2(s,tp)*pop2(s,tp),tp);
    178     '/'://可能除以0,需要判断
    179      begin
    180       w2:=pop2(s,tp);
    181       w1:=pop2(s,tp);
    182       k:=chu(w1,w2);
    183       if k=-maxlongint then
    184        exit(-maxlongint)
    185       else
    186        push2(s,k,tp);
    187      end;
    188     '^':
    189      begin
    190       w2:=pop2(s,tp);
    191       w1:=pop2(s,tp);
    192       push2(s,cf(w1,w2),tp);
    193      end;
    194    end;
    195   inc(i);
    196  end;
    197  work:=pop2(s,tp);
    198 end;
    199 procedure k;
    200 var st1,st2,s1,s2:string;
    201     ch:char;
    202     r,u:longint;
    203     t1,t2:extended;
    204 begin
    205  readln(e);
    206  while pos(chr(32),e)<>0 do
    207   delete(e,pos(chr(32),e),1);
    208  create(e,a);
    209  tag:=true;//判断两个表达式是否相等
    210  c1:=0;
    211  c2:=0;
    212  for jj:=1 to 20 do
    213   begin
    214    x3:=random;
    215    x1:=work(st,x3);
    216    x2:=work(a,x3);
    217    if (x1=1)or(x2=1) then
    218     begin
    219      if abs(x1-x2)<1e-10 then
    220       continue
    221      else
    222       begin
    223        tag:=false;
    224        break;
    225       end;
    226     end;
    227    if (x1=-maxlongint)or(x2=-maxlongint) then
    228     begin
    229      if x1=-maxlongint then
    230       inc(c1);
    231      if x2=-maxlongint then
    232       inc(c2);
    233      continue;
    234     end
    235    else
    236     begin
    237      str(x1,st1);
    238      str(x2,st2);
    239      s1:=copy(st1,1,10);
    240      s2:=copy(st2,1,10);
    241      t1:=ln(abs(x1));
    242      t2:=ln(abs(x2));
    243      if not((x1=x2)or(((x1>0)and(x2>0)or(x1<0)and(x2<0))and(round(t1)=round(t2))and(s1=s2))) then 这里是一个很重要的判断是否相等的句子,可以自行思考一下
    244       begin
    245        tag:=false;
    246        break;
    247       end;
    248     end;
    249   end;
    250  if (c1=0)and(c2>0)or(c1>0)and(c2=0) then
    251   tag:=false;
    252  if tag then 
    253   write(chr(ii+64));
    254 end;
    255 begin
    256  randomize;//随机化
    257  readln(e);
    258  while pos(chr(32),e)<>0 do
    259   delete(e,pos(chr(32),e),1);//数据有坑,无缘无故会有许多多余的空格
    260  create(e,st);
    261  readln(n);
    262  for ii:=1 to n do
    263   begin
    264    if ii=14 then
    265     n:=n;
    266    k;
    267   end;
    268  writeln;
    269 end.
  • 相关阅读:
    Python_soket
    Python_正则表达式语法
    Python_math模块
    Python_random模块
    Python_os模块
    Python_time模块
    Java技能树-图片版
    读书笔记---《编写可读代码的艺术》
    Java代码优化建议
    Git常用命令
  • 原文地址:https://www.cnblogs.com/PengBoLiuXu/p/4499307.html
Copyright © 2011-2022 走看看