• 1107 等价表达式


    1107 等价表达式

     

    2005年NOIP全国联赛提高组

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
     
    题目描述 Description

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

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

    这个选择题中的每个表达式都满足下面的性质:
    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……

    输入描述 Input Description

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

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

    输出描述 Output Description

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

    样例输入 Sample Input

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

    样例输出 Sample Output

    AC

    数据范围及提示 Data Size & Hint

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

    分类标签 Tags 点此展开 

     
     
    题解:
    表达式计算
    就是压栈处理;

    设a为一个质数,模数为另一个质数,然后暴力算多项式的答案,如果答案相等就认为两个多项式相等。

    这种hash有出错概率的题为什么还是要用hash呢?因为出错的概率实在太小了,a和模数的值取得好出题人根本没法卡。

    (不一定非要取3、4次质数,主要是rp)

     

    注意有空格。

    裸的表达式计算

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    #define N 256
    int num[N],p=1,i,z;
    char symbol[N],s[N],t[N],ans[N];
    inline void push(){
        symbol[++p]=s[i];
    }
    inline void pop(){
        switch(symbol[p--]){
            case '^':num[p]=pow(num[p],num[p+1]);break;
            case '+':num[p]+=num[p+1];break;
            case '-':num[p]-=num[p+1];break;
            case '*':num[p]*=num[p+1];break;
            case '/':num[p]/=num[p+1];break;
        }
    }
    inline bool can(){
        if((s[i]=='+'||s[i]=='-')&&symbol[p]!='(') return 1;
        if(s[i]=='^'&&symbol[p]=='^') return 1;
        if((s[i]=='*'||s[i]=='/')&&(symbol[p]=='*'||symbol[p]=='/')) return 1;
        return 0;
    }
    inline void deal(){
        gets(s);
        int len=strlen(s);
        s[len]=')';symbol[p]='(';
        while(i<len){
            while(s[i]=='(') push(),i++;
            int x(0);
            while(s[i]>='0'&&s[i]<='9') x=x*10+s[i++]-'0';
            num[p]=x;
            do{
                if(s[i]==')'){
                    while(symbol[p]!='(') pop();
                    num[--p]=num[p+1];
                }
                else{
                    while(can()) pop();
                    push();
                }
                i++;
            }while(i<len&&s[i-1]==')');
        }
    }
    int main(){
        deal();
        printf("%d
    ",num[0]);
        return 0;
    }

    本题AC代码:

     

    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define ll long long
    const int N=10003;
    const int a=10007;
    const int p=100007;
    char s[N],c[N],sym[N];
    int m,num[N],yxj[N],topnum,topch;
    int get(char ch){
        if(ch=='+'||ch=='-') return 1;
        if(ch=='*') return 2;
        if(ch=='^') return 3;
    }
    int ipow(int a,int b){
        ll t=1;
        for(int i=1;i<=b;i++)
            t=t*a%p;
        return (int)t;
    }
    int cal(char ch,int a,int b){
        switch(ch){
            case '^':return ipow(a,b);break;
            case '+':return (a+b)%p;break;
            case '-':return (a-b+p)%p;break;
            case '*':return (int)(1ll*a*b%p);break;
        }
    }
    bool can(char ch){
        return (ch=='+'||ch=='-'||ch=='*'||ch=='^'||ch=='('||ch==')');
    }
    int deal() {
        int len=strlen(s),tmp=0,j=100,k;
        c[0]=' ';
        for(int i=0;i<len;++i)
            if(s[i]!=' ') c[++tmp]=s[i];
        c[tmp+1]=' ';
        len=tmp;tmp=1;topnum=topch=0;
        while(tmp<=len) {
            if(can(c[tmp])){
                if(c[tmp]=='(') j+=10;
                else if(c[tmp]==')') j-=10;
                else{
                    k=get(c[tmp]);
                    while(topch&&yxj[topch]>=k+j) {
                        num[topnum-1]=cal(sym[topch],num[topnum-1],num[topnum]);
                        --topnum;--topch;
                    }
                    sym[++topch]=c[tmp];yxj[topch]=k+j;
                }
                ++tmp;
            } 
            else{
                if(c[tmp]=='a') num[++topnum]=a,++tmp;
                else{
                    k=0;
                    for(;c[tmp]>='0' && c[tmp]<='9' && tmp<=len;++tmp)k=k * 10+c[tmp]-'0';
                    num[++topnum]=k;
                }
            }
        }
        while(topch){
            num[topnum-1]=cal(sym[topch],num[topnum-1],num[topnum]);
            --topnum;--topch;
        }
        return num[1];
    }
    int main() {
        gets(s);
        int res=deal();
        scanf("%d
    ",&m);
        for(int i=1;i<=m;++i){
            gets(s);
            int now=deal();
            if(now==res) putchar(64+i);
        }
        puts("");
        return 0;
    }
  • 相关阅读:
    WINCE6.0去掉桌面快捷方式
    dp和px,那些不得不吐槽的故事——Android平台图
    Redpine Signals RS9110-N-11-02 Wi-Fi解决方案
    Redpine的Lite-Fi解决方案获Wi-Fi CERTIFIED认证
    ARM处理器全解析:A8/A9/A15都是什么?
    Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) E
    Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) D
    Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) C
    Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) B
    Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) A
  • 原文地址:https://www.cnblogs.com/shenben/p/5703286.html
Copyright © 2020-2023  润新知