题目链接:http://dsalgo.openjudge.cn/stackqueue/5/
AC代码
#include <iostream>
#include <cctype>
#include <algorithm>
#include <stack>
#include <string>
#include <map>
#include <vector>
using namespace std;
#define isnumber(c) ((c) >= '0' && (c) <= '9')
int vals[128];
enum NodeType {
NUM, VAR, SYM,
};
struct Element {
NodeType type;
int n;
char c;
};
vector<Element> infix2postfix(const char *infix) {
vector<Element> result;
stack<char> symStack;
for (char *it = (char *) infix; *it;) {
char c = *it;
if (isspace(c)) ++it;
else if (isalpha(c)) result.push_back({VAR, 0, c}), ++it;
else if (isnumber(c)) result.push_back({NUM, (int) strtol(it, &it, 10), 0});
else if (c == '(') symStack.push('('), ++it;
else if (c == '+' || c == '-' || c == '*') {
while (!symStack.empty() && symStack.top() != '(') {
result.push_back({SYM, 0, symStack.top()});
symStack.pop();
}
symStack.push(c);
++it;
} else if (c == ')') {
while (symStack.top() != '(') {
result.push_back({SYM, 0, symStack.top()});
symStack.pop();
}
symStack.pop();
++it;
}
}
while (!symStack.empty())
result.push_back({SYM, 0, symStack.top()}), symStack.pop();
return result;
}
int getVal(vector<Element> postfix) {
stack<int> valStack;
for (auto x:postfix) {
switch (x.type) {
case NUM:
valStack.push(x.n);
break;
case VAR:
valStack.push(vals[x.c]);
break;
case SYM:
int element2 = valStack.top();
valStack.pop();
int element1 = valStack.top();
valStack.pop();
switch (x.c) {
case '+':
valStack.push(element1 + element2);
break;
case '-':
valStack.push(element1 - element2);
break;
case '*':
valStack.push(element1 * element2);
break;
}
break;
}
}
return valStack.top();
}
char BUFF[100];
int main() {
gets(BUFF);
int N = atoi(BUFF);
for (int i = 0; i < 128; ++i) vals[i] = i;
while (N--) {
auto s1 = infix2postfix(gets(BUFF)), s2 = infix2postfix(gets(BUFF));
cout << ((getVal(s1) == getVal(s2)) ? "YES" : "NO") << endl;
}
}
解题思路
其实,如果两个多项式不相等,那么他们在被随机赋予某一个值时相等的可能性很小,因此这里直接赋了一个值(这里选择每个字母对应它的ascii码数值),然后就诈和AC了。
如果要是认真解这道题的话,除了像开发MATLAB符号运算工具包一样手写多项式运算之外,其实也可以利用代数基本定理,给每个变量赋一些值来进行判断,最终能得到可以理论上证明正确的判断,但是感觉那样是自找麻烦。不放心的话,也还可以多试几个数就差不多了。
此外,python里有一个叫作eval
的流氓函数,将一个字符串当成语句直接执行,那么上述的算法可以用python简单实现
def expreq(exp1,exp2):
for x in range(97,123):
exp1 = exp1.replace(chr(x), str(x))
exp2 = exp2.replace(chr(x), str(x))
return eval(exp1) == eval(exp2)
for x in range(int(input())):
print("YES" if expreq(input(),input()) else "NO")
写这个程序的时候用到了一个<stdlib.h>
里的函数,叫strtoi
,它的用法,有趣。