题解 P1054 【等价表达式】

· · 题解

由于不太好处理带有未知数的表达式,我们考虑将a取值,然后带入计算。

我们只需要随机取多次a的值检验,即可保证极高的正确率。

洛谷的数据是windows环境下造的,行尾有一个多余的'\r',判断空白字符的时候要注意一下。

所以用栈转换称后缀表达式,每次用栈计算即可。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

#define For(i,_beg,_end) for(int i=(_beg),i##end=(_end);i<=i##end;++i)
#define Rep(i,_beg,_end) for(int i=(_beg),i##end=(_end);i>=i##end;--i)

template<typename T>T Max(const T &x,const T &y){return x<y?y:x;}
template<typename T>T Min(const T &x,const T &y){return x<y?x:y;}
template<typename T>int chkmax(T &x,const T &y){return x<y?(x=y,1):0;}
template<typename T>int chkmin(T &x,const T &y){return x>y?(x=y,1):0;}
template<typename T>void read(T &x){
    T f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(x=0;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    x*=f;
}

typedef unsigned long long LL;
const int N=110;
int n,top,suf[N][N],lvl[256],m[N];
LL Sta[N];
char sta[N],str[N];
bool b[N];

void Work(int id){
    int len=strlen(str+1),cnt=0;top=0;
    For(i,1,len){
        if(str[i]=='a')suf[id][++cnt]=-1;
        else if(str[i]>='0'&&str[i]<='9'){
            int j=i,x=0;
            while(str[j]>='0'&&str[j]<='9')x=x*10+str[j++]-'0';
            i=j-1;suf[id][++cnt]=x;
        }
        else if(str[i]=='('||str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='^'){
            while(top&&sta[top]!='('&&lvl[sta[top]]>=lvl[str[i]]){
                suf[id][++cnt]=sta[top]+10000;
                top--;
            }
            sta[++top]=str[i];
        }
        else if(str[i]==')'){
            while(top&&sta[top]!='(')suf[id][++cnt]=sta[top--]+10000;
            top--;
        }
    }
    while(top){
        if(sta[top]!='(')suf[id][++cnt]=sta[top]+10000;
        top--;
    }
    m[id]=cnt;
}
LL power(LL x,LL y){
    LL res=1;
    for(;y;y>>=1,x*=x) if(y&1)res*=x;
    return res;
}
LL calc(LL x,LL y,char c){
    if(c=='+')return x+y;
    if(c=='-')return x-y;
    if(c=='*')return x*y;
    if(c=='^')return power(x,y);
}
LL Calc(int id,int a){
    top=0;
    For(i,1,m[id]){
        if(suf[id][i]==-1)Sta[++top]=a;
        else if(suf[id][i]>10000){
            LL res=calc(Sta[top-1],Sta[top],suf[id][i]-10000);
            Sta[--top]=res;
        }
        else Sta[++top]=suf[id][i];
    }
    return Sta[top];
}

int main(){
    lvl['+']=lvl['-']=0;
    lvl['*']=1;lvl['^']=2;
    lvl['(']=lvl[')']=3;
    cin.getline(str+1,N);
    read(n);getchar();Work(0);
    For(i,1,n){
        cin.getline(str+1,N);
        Work(i);
    }
    For(i,1,100){
        int x=rand();
        LL temp=Calc(0,x);
        For(j,1,n)
            if(Calc(j,x)!=temp)b[j]=true;
    }
    For(i,1,n) if(!b[i])putchar('A'+i-1);
    putchar(10);
    return 0;
}