P1054 等价表达式

题目描述

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

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

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

  1. 表达式只可能包含一个变量‘aa’。
  2. 表达式中出现的数都是正整数,而且都小于1000010000。
  3. 表达式中可以包括四种运算+(加),-(减),*(乘),^(乘幂),以及小括号(,)。小括号的优先级最高,其次是^,然后是*,最后是+-+-的优先级是相同的。相同优先级的运算从左到右进行。(注意:运算符+-*^以及小括号()都是英文字符)
  4. 幂指数只可能是11到1010之间的正整数(包括11和1010)。
  5. 表达式内部,头部或者尾部都可能有一些多余的空格。

下面是一些合理的表达式的例子:

((a^1) ^ 2)^3a*a+a-a((a+a))9999+(a-a)*a1 + (a -1)^31^10^9………

输入输出格式

输入格式:

第一行给出的是题干中的表达式。

第二行是一个整数n(2 \le n \le 26)n(2≤n≤26),表示选项的个数。后面nn行,每行包括一个选项中的表达式。这nn个选项的标号分别是A,B,C,D…A,B,C,D…

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

输出格式:

一行,包括一系列选项的标号,表示哪些选项是和题干中的表达式等价的。选项的标号按照字母顺序排列,而且之间没有空格。

输入输出样例

输入样例#1:

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

输出样例#1:

AC

说明

对于30%的数据,表达式中只可能出现两种运算符‘+’和-
对于其它的数据,四种运算符+-*^在表达式中都可能出现。
对于全部的数据,表达式中都可能出现小括号()

2005年提高组第四题

Solution:

  Noip的题目,满满的恶意((?◇?)?读入有毒啊!)。

  读入一行字符串,本题不能用gets或者cin.getline(因为我试了),所以得手写读入(判断换行‘\n‘和回车‘\r‘)。

  思路就是随便代10个数计算每个表达式的值,然后判断是否都相等就好了。

  求的话可以用双栈模拟(一个存数,一个单调维护符号优先级),或者递归求,递归过程直接区间从后往前,用hash的思路统计算术优先级(优先级:‘(‘>‘^‘>‘*‘>‘+‘=‘-‘>‘)‘),优先运算优先级高的就好了。

代码:

/*Code by 520 -- 8.31*/
#include<bits/stdc++.h>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=55,mod=1e9+7;
int n,len[N],sum[N];
char s[27][N],t[N];

il ll fast(ll x,ll k){
    ll ans=1;
    while(k){
        if(k&1) ans=ans*x%mod;
        k>>=1;
        x=x*x%mod;
    }
    return ans;
}

int p[N];
ll dfs(char *s,int l,int r,int x){
    int tot=0,minn=0x7fffffff,pos=l,cnt=0,num=0;
    memset(p,0x3f,sizeof(p));
    Bor(i,l,r){
        if(s[i]==‘)‘) tot+=100;
        if(s[i]==‘(‘) tot-=100;
        if(s[i]==‘^‘) p[i]=tot+3,cnt++;
        if(s[i]==‘*‘) p[i]=tot+2,cnt++;
        if(s[i]==‘+‘||s[i]==‘-‘) p[i]=tot+1,cnt++;
        if(minn>p[i]) minn=p[i],pos=i;
    }
    if(!cnt){
        For(i,l,r) if(s[i]==‘a‘)return x;
        For(i,l,r) if(isdigit(s[i])) num=(num<<3)+(num<<1)+(s[i]^48);
        return num;
    }
    if(s[pos]==‘^‘) return fast(dfs(s,l,pos-1,x),dfs(s,pos+1,r,x));
    if(s[pos]==‘*‘) return dfs(s,l,pos-1,x)*dfs(s,pos+1,r,x)%mod;
    if(s[pos]==‘+‘) return (dfs(s,l,pos-1,x)+dfs(s,pos+1,r,x))%mod;
    if(s[pos]==‘-‘) return (dfs(s,l,pos-1,x)-dfs(s,pos+1,r,x))%mod;
    return 0;
}

il void get(char *a){
    char c=getchar();
    int cnt=0;
    while(c==‘\n‘||c==‘\r‘) c=getchar();
    while(c!=‘\n‘&&c!=‘\r‘) a[cnt++]=c,c=getchar();
    a[cnt]=‘\0‘;
}

int main(){
    get(t),len[0]=strlen(t);
    cin>>n;
    For(i,1,n) get(s[i]),len[i]=strlen(s[i]);
    For(i,0,10) sum[i]=dfs(t,0,len[0]-1,i-5);
    For(i,1,n) {
        bool f=0;
        For(j,0,10) if(sum[j]!=dfs(s[i],0,len[i]-1,j-5)){f=1;break;}
        if(!f)printf("%c",‘A‘+i-1);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/five20/p/9571414.html

时间: 2024-11-13 06:39:05

P1054 等价表达式的相关文章

数据结构--栈 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 等价表达式 解题报告

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

等价表达式(noip2005)

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

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

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

NOIP2005 等价表达式

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

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

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