等价表达式 (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.
时间: 2024-10-08 17:39:29

等价表达式 (codevs 1107)题解的相关文章

数据结构--栈 codevs 1107 等价表达式

codevs 1107 等价表达式 2005年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的. 这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这

1107 等价表达式

1107 等价表达式 2005年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的. 这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来

等价表达式

栈的经典题目,开两个栈,一个存符号,一个存数字: 分情况讨论: 1.如果当前读到的运算符优先级小于栈顶,就进行一次运算,直到大于等于: 2.如果读到数字用类似读入优化的方法读入进来: 3.如果当前符号为"("则直接入栈: 4.如果当前符号为")"则进行运算直到碰到"(": 5.小技巧 在式子开头加"(",末尾加")": 6.遇到a,让a等于质数: 7.多次取模,因为有可能爆long long,模不同的质数,

和指针相关的两个特殊运算符,和相关的等价表达式

和指针相关的两个特殊运算符: 一."&" 取地址运算符,通过&运算符可以取出普通变量的地址: 二."*"  有两种意义: 1.  为指针标志: 是否为指针标志主要看前面是否有类型,此处有一个int 2.  为指针运算符:    在等号右面为取值.*可以取出指针变量所指向的普通变量的值.   在等号左面为赋值.*可以将指针变量所指向的普通变量的值,修改为其他. 3.  为乘法运算符.当且仅当左右的都为变量时.略. 如 int a, b =20, c=3

NOIP2005 等价表达式 解题报告

明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的. 这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题.假设你是明明,能完成这个任务吗? 这个选择题中的每个表达式都满足下面的性质: 1.  表达式只可能包含一个变量‘a’. 2.  表达式中出现的数都是正整数,而且都小于10000. 3.

等价表达式(noip2005)

3.等价表达式 [问题描述]    兵兵班的同学都喜欢数学这一科目,中秋聚会这天,数学课代表给大家出了个有关代数表达式的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的.    这个题目手算很麻烦,因为数学课代表对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题.假设你是数学课代表,能完成这个任务吗? 这个选择题中的每个表达式都满足下面的性质: 1. 表达式只可能包含一个变量

[Codevs 1107][NOIP 1107]等价表达式

题目连接:http://codevs.cn/problem/1107/ 一道很神奇的题目.对于算术表达式一类的问题,可以采用编译原理里的后缀表达式的方式来做,具体做法是分别维护两个栈,一个栈里保存表达式里的数字,另一个栈里保存表达式里的运算符,给每种运算符一个优先级,我们要维护这个栈的单调性,每次读入运算符中的数字或运算符,读入的是运算符时,若这个运算符比栈顶的运算符优先级低,就弹出栈顶元素,把栈顶的运算符和数字栈里栈顶的两个数字拿出来做一次运算,运算结果再入数字栈,直到运算符栈的栈顶元素优先级

等价表达式(codevs 1107 答案错误)

题目描述 Description 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的. 这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题.假设你是明明,能完成这个任务吗? 这个选择题中的每个表达式都满足下面的性质:1.表达式只可能包含一个变量‘a’.2.表达式中出现的数都是正整数,而且都

[Codevs 1107][NOIP 1107]等效表达

主题连接:http://codevs.cn/problem/1107/ 一道非常奇妙的题目. 对于算术表达式一类的问题,能够採用编译原理里的后缀表达式的方式来做.详细做法是分别维护两个栈,一个栈里保存表达式里的数字,还有一个栈里保存表达式里的运算符,给每种运算符一个优先级,我们要维护这个栈的单调性,每次读入运算符中的数字或运算符,读入的是运算符时,若这个运算符比栈顶的运算符优先级低,就弹出栈顶元素.把栈顶的运算符和数字栈里栈顶的两个数字拿出来做一次运算,运算结果再入数字栈.直到运算符栈的栈顶元素