等价表达式(noip2005)

3.等价表达式

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

这个选择题中的每个表达式都满足下面的性质:

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……
【输入文件】

第一行给出的是题干中的表达式。第二行是一个整数n(2 <= n <= 26),表示选项的个数。后面n行,每行包括一个选项中的表达式。这n个选项的标号分别是A,B,C,D……

输入中的表达式的长度都不超过50个字符,而且保证选项中总有表达式和题干中的表达式是等价的。

【输出文件】
输出文件包括一行,这一行包括一系列选项的标号,表示哪些选项是和题干中的表达式等价的。选项的标号按照字母顺序排列,而且之间没有空格。
【样例输入】
( a + 1) ^2
3
(a-1)^2+4*a
a + 1+ a
a^2 + 2 * a * 1 + 1^2 + 10 -10 +a -a
【样例输出】
AC
【数据规模】
对于30%的数据,表达式中只可能出现两种运算符‘+’和‘-’;
对于其它的数据,四种运算符‘+’,‘-’,‘*’,‘^’在表达式中都可能出现。
对于全部的数据,表达式中都可能出现小括号‘(’和‘)’。

解析:

(1) 如果直接判断两个表达式等价比较麻烦,笔者也没想出来如何比较。但是我们可以用代数法,以不同的a值代入各式,快速排除那些结果不同的表达式,留下的便是等价的了。(注意,这里的a值最好随机生成,并且最好生成多组,这样基本能保证万无一失)。

(2)表达式求值,有两种方法,一种是中缀转后缀,然后求值;另一种就是中缀表达式直接求值,笔者喜欢第二种。

中缀表达式直接求值:

首先给表达式中所有的运算符和括号根据运算规则都规定不同的等级。根据规定的等级可以求出表达中每个运算符的等级。然后递归求解:

(1)找到级别最低的运算符opt,将表达式分成左右两部分;

(2)求opt左边的表达式的值s0;

(3)求opt左边的表达式的值s1;

(4)s0  opt s1 。

运算符的级别:


符号


+  -


*   /


^


(


)


优先级


1


2


3


3


-3

{中缀表达式直接求值:给每个运算符根据运算规则制定不同的等级,运算时先找出表达式中级别最低的运算符,将表达式分成左右两部分,先求左边

再求右边,最后求整个表达式的运算结果。}
var
  a:array[0..30] of string;
  f:array[0..30] of boolean;
  b:array[1..4] of integer;
  e:array[0..30,1..4] of int64;
  h:array[1..500] of integer;
  n:integer;
  procedure level(s:string);
  var
    i,len,base:integer;
  begin
    len:=length(s);
    for i:=1 to len do h[i]:=maxint;
    base:=0;
    for i:=1 to len do
      case s[i] of
        ‘(‘:inc(base,3);
        ‘)‘:dec(base,3);
        ‘+‘,‘-‘:h[i]:=base+1;
        ‘*‘:h[i]:=base+2;
        ‘^‘:h[i]:=base+3;
      end;
  end;
  procedure init;
  var i:integer;
  begin
    assign(input,‘equal.in‘); reset(input);
    readln(a[0]);
    readln(n);
    for i:=1 to n do readln(a[i]);
    close(input);
  end;
  function data(L,r,x,t:integer):integer;
  var i:longint;
  begin
    while (a[t][L]=‘(‘) or(a[t][L]=‘ ‘)do inc(L);
    while (a[t][r]=‘)‘)or (a[t][r]=‘ ‘) do dec(r);
    data:=0;
    if a[t][L]=‘a‘ then exit(x);
    for i:=L to r do  data:=data*10+ord(a[t][i]) -48;
  end;
  function find(L,r:integer):int64;
  var i,min:integer;
  begin
    min:=maxint;
    find:=0;
    for i:=r downto L do
      if h[i]<min then begin min:=h[i];find:=i; end;
  end;
  function opt(u,k,v:int64;t:integer):int64;
  var i:integer;
  begin
    case a[t][k] of
         ‘+‘:opt:=u+v;
         ‘-‘:opt:=u-v;
         ‘*‘:opt:=u*v;
         ‘^‘:begin
               opt:=1;
               for i:=1 to v do opt:=opt*u;
             end;
     end;
  end;
  function work(L,r,x,i:integer):int64;
  var k,u,v:int64;
  begin
    k:=find(L,r);
    if k=0 then exit(data(l,r,x,i));
    u:=work(L,k-1,x,i);
    v:=work(K+1,r,x,i);
    work:=opt(u,k,v,i);
  end;
  procedure main;
  var i,j,len:integer;
      bo:boolean;
  begin
    randomize;
    for i:=1 to 4 do
      b[i]:=random(1000);

    for i:=0 to n do
      begin
        level(a[i]);
        len:=length(a[i]);
        for j:=1 to 4 do   e[i,j]:=work(1,len,b[j],i);
        if i>0 then
        begin
          bo:=true;
          for j:=1 to 4 do if e[i,j]<>e[0,j] then bo:=false;
          if bo then write(chr(64+i));
        end;
      end;
  end;
begin
  assign(output,‘equal.out‘);rewrite(output);
  init;
  main;
  close(output);
end.

时间: 2024-11-08 09:40:31

等价表达式(noip2005)的相关文章

NOIP2005 等价表达式 解题报告

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

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

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

等价表达式

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

1107 等价表达式

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

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

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

NOIP2005 等价表达式

做题记录: 2016-08-10 23:35:09 背景 NOIP2005 提高组 第四道 描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的. 这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题.假设你是明明,能完成这个任务吗? 这个选择题中的每个表达式都满足下面的性质: 1.  

等价表达式 (codevs 1107)题解

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

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

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

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

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