明明进了中学之后,学到了代数表达式。有一天,他碰到一个很麻烦的选择题。这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数表达式是和题干中的表达式等价的。
这个题目手算很麻烦,因为明明对计算机编程很感兴趣,所以他想是不是可以用计算机来解决这个问题。假设你是明明,能完成这个任务吗?
这个选择题中的每个表达式都满足下面的性质:
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%的数据,表达式中只可能出现两种运算符‘+’和‘-’;
对于其它的数据,四种运算符‘+’,‘-’,‘*’,‘^’在表达式中都可能出现。
对于全部的数据,表达式中都可能出现小括号‘(’和‘)’。
分着存两个栈,一个记录数字,另一个记录运算符,由于数可能比较大,可以mod一个数,将a用特殊值替换,防止重复,可以多换几个值。
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
stack<long long > snum,sopt;
const int mod=10007;
int n;
long long ans;
void add(int num) {
int opt;
long long temp1,temp2;
while(!sopt.empty()) {
if(sopt.top()<=num) {
if(sopt.top()==5) {
sopt.pop();
break;
}
opt=sopt.top();
sopt.pop();
temp2=snum.top();
snum.pop();
temp1=snum.top();
snum.pop();
if(opt==4) snum.push((temp1+temp2)%mod);
if(opt==3) snum.push(temp1-temp2);
if(opt==2) snum.push((temp1*temp2)%mod);
else if(opt==1){
int t=1;
for(int i=1;i<=temp2;i++)
t=(t*temp1)%mod;
snum.push(t);
}
}
else break;
}
return;
}
int main() {
long long num=0;
char ch;
while(scanf("%c",&ch)==1&&ch!='\n'){
if(ch==' ') continue;
if(ch=='(') sopt.push(5);
else if(ch==')') {
if(num>0) snum.push(num);
add(6);
num=0;
}
else if(ch=='+') {
if(num>0) snum.push(num);
add(4);
sopt.push(4);
num=0;
}
else if(ch=='-') {
if(num>0) snum.push(num);
add(3);
sopt.push(3);
num=0;
}
else if(ch=='*') {
if(num>0) snum.push(num);
add(2);
sopt.push(2);
num=0;
}
else if(ch=='^') {
if(num>0) snum.push(num);
add(1);
sopt.push(1);
num=0;
}
else if(ch=='a') num=3;
else num=(num*10+ch-'0')%mod;
}
if(num>0) snum.push(num);
add(10);
ans=snum.top();
snum.pop();
cin>>n;
getchar();
for(int i=1;i<=n;i++) {
num=0;
while(scanf("%c",&ch)==1&&ch!='\n'){
if(ch==' ') continue;
if(ch=='(') sopt.push(5);
else if(ch==')') {
if(num>0) snum.push(num);
add(6);
num=0;
}
else if(ch=='+') {
if(num>0) snum.push(num);
add(4);
sopt.push(4);
num=0;
}
else if(ch=='-') {
if(num>0) snum.push(num);
add(3);
sopt.push(3);
num=0;
}
else if(ch=='*') {
if(num>0) snum.push(num);
add(2);
sopt.push(2);
num=0;
}
else if(ch=='^') {
if(num>0) snum.push(num);
add(1);
sopt.push(1);
num=0;
}
else if(ch=='a') num=3;
else num=(num*10+ch-'0')%mod;
}
if(num>0) snum.push(num);
add(10);
int aans=snum.top();
if(ans==aans) printf("%c",'A'+i-1);
snum.pop();
}
return 0;
}
本文介绍了如何利用计算机编程解决一个代数表达式等价性判断的数学问题。题目要求判断给定的一系列选项中,哪些表达式与初始的代数表达式等价。每个表达式只包含变量'a',正整数,四种运算符以及小括号,并且规定了运算的优先级。通过编写程序,可以高效地找出等价的选项,样例输入和输出展示了具体的判断过程。数据规模和提示表明,实际问题可能涉及更复杂的运算符组合和括号使用。

815

被折叠的 条评论
为什么被折叠?



