Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 3458 | Accepted: 1174 |
Description
You are to write a program to read different formulas and determine whether or not they are arithmetically equivalent.
Input
- Single letter variables (case insensitive).
- Single digit numbers.
- Matched left and right parentheses.
- Binary operators +, - and * which are used for addition, subtraction and multiplication respectively.
- Arbitrary number of blank or tab characters between above tokens.
Note: Expressions are syntactically correct and evaluated from left to right with equal precedence (priority) for all operators. The coefficients and exponents of the variables are guaranteed to fit in 16-bit integers.
Output
Sample Input
3 (a+b-c)*2 (a+a)+(b*2)-(3*c)+c a*2-(a+c)+((a+c+e)*2) 3*a+c+(2*e) (a-b)*(a-b) (a*a)-(2*a*b)-(b*b)
Sample Output
YES YES NO
题意:给你t组数据,每组数据有两行字符串,问你这两个字符串计算的结果是否相同,注意()的优先和*的优先级别。
思路:不知道为什么这样做可以AC,或者我们可以把下面这种做法理解成提比的强行AC技能(提比见图)。
对于每个a-z把它变成ASCII所对应的数,即97-124。然后运算,过程中用int即可,其实要是数据不水的话超long long 也是很有可能的,但不知为什么超了也能得到正确的结果,可能是原来的数一样大,超完int后也一样大吧。然后对于* + - 我用-999997983、-999997973、-999997963代替,(我假设它没有出现这样的中间数据→_→)。如果不放心的话struct node { }判断它的类型也行,就是麻烦点。
用两个栈,A栈先存放数据,当读到一个 ')' 的时候,让A栈的数先转移到B栈,转移的时候将*的运算都做出来,然后再由B栈转移到A栈,这时再将+-的运算做出来,这样就能保证优先级了。
PS:题目有说字符串中间可能会有空格。
提比强行AC的代码如下:
#include<cstdio>
#include<cstring>
#include<stack>
using namespace std;
char s[1010];
stack<int> st1;
stack<int> st2;
int num[1010];
int len;
int solvechar(char a) //将字符转换成数字
{ if(a==' ')
return -10;
else if(a=='(')
return -999997993;
else if(a==')')
return -2;
else if(a=='+')
return -999997983;
else if(a=='-')
return -999997973;
else if(a=='*')
return -999997963;
int k=a-'0';
if(k>=0 && k<=9)
return k;
k=a-'a'+97;
return k;
}
void jisuan()
{ int a,b,c,d,k;
while(!st1.empty() && st1.top()!=-999997993)//先将st1中到(前的东西转移到st2中
{ k=st1.top();
st1.pop();
if(k==-999997963) //计算乘法
{ a=st1.top();
st1.pop();
b=st2.top();
st2.pop();
c=a*b;
st2.push(c);
}
else
st2.push(k);
}
if(!st1.empty()) //除去(
st1.pop();
while(!st2.empty()) //将st2中的数转移回st1
{ k=st2.top();
st2.pop();
if(k==-999997983) //计算加法
{ a=st1.top();
st1.pop();
b=st2.top();
st2.pop();
c=a+b;
st1.push(c);
}
else if(k==-999997973) //计算减法
{ a=st1.top();
st1.pop();
b=st2.top();
st2.pop();
c=a-b;
st1.push(c);
}
else
st1.push(k);
}
}
int solve()
{ len=strlen(s);
int i,j,k,pos=0,m=0;
for(i=0;i<=len-1;i++)
{ k=solvechar(s[i]);
if(k==-10)
continue;
if(k==-2) //每次到)的时候进行计算
jisuan();
else
st1.push(k);
}
jisuan();
return st1.top();
}
int main()
{ int t,ans1,ans2;
scanf("%d",&t);
getchar();
while(t--)
{ gets(s);
ans1=solve();
st1.pop();
gets(s);
ans2=solve();
st1.pop();
if(ans1==ans2)
printf("YES\n");
else
printf("NO\n");
}
}
再附上网上的测试数据和运行出来的结果,我又加了两个ans分别为多少。
15
2 * 1-3+( 2 * 5 )
9
8
((2 * 4)-7*2+(5-(6 * 7)+ 4 ) )
(a)+(((b)))*(a-(2*b))*(1)*(b-2+c+a)*(d+e+a-f+b)
a * b * a * b * a * a * 9 * b * a * 8 * b * 7 * c * 9 * a
(((a)*a)*a * b * ( a-b)*( a - b )*(a-c)*(a+b))*(((b-c)))
b*a*(a*(a*(b-c))*((a+b)*(a-c))*(a-b)*(a-b))
(w-a)+(a-b)-(c+a)*4+d
(a-w)+(b-a)-(a+c)*d+4
a-b*c+a+d*a-c*a+e*a*b*9*z*8*w*7
(a*a*a*a*b*(c-b+1)+(a*b*(a*(a*d-c)+e)))*9*z*8*w*7
(a+b-c)*2
(a+a)+(b*2)-(3*c)+c
a*2-(a+c)+( (a+c+e)*2)
3*a+c+(2*e)
(a-b)*(a-b)
(a*a)-(2*a*b)-(b*b)
(a-b)*(a-b)
(a*a)-(2*a*b)+(b*b)
a*b
b*a
1+a-a
b+1-b
2+1+a+1
1+3+a
(1+a+b)+7 +c+(d)
a+c+b+d +1+1+(1+(2+3))
((((1)+a)+b))+6 +c+(d)
a+c+b+d +1+1+(1+(2+3))
15
2 * 1-3+( 2 * 5 )
9
ans 9 9
YES
8
((2 * 4)-7*2+(5-(6 * 7)+ 4 ) )
ans 8 -39
NO
(a)+(((b)))*(a-(2*b))*(1)*(b-2+c+a)*(d+e+a-f+b)
a * b * a * b * a * a * 9 * b * a * 8 * b * 7 * c * 9 * a
ans -832897199 758784640
NO
(((a)*a)*a * b * ( a-b)*( a - b )*(a-c)*(a+b))*(((b-c)))
b*a*(a*(a*(b-c))*((a+b)*(a-c))*(a-b)*(a-b))
ans 522623692 522623692
YES
(w-a)+(a-b)-(c+a)*4+d
(a-w)+(b-a)-(a+c)*d+4
ans -663 -19617
NO
a-b*c+a+d*a-c*a+e*a*b*9*z*8*w*7
(a*a*a*a*b*(c-b+1)+(a*b*(a*(a*d-c)+e)))*9*z*8*w*7
ans -1401776035 -1368750848
NO
(a+b-c)*2
(a+a)+(b*2)-(3*c)+c
ans 192 192
YES
a*2-(a+c)+( (a+c+e)*2)
3*a+c+(2*e)
ans 592 592
YES
(a-b)*(a-b)
(a*a)-(2*a*b)-(b*b)
ans 1 -19207
NO
(a-b)*(a-b)
(a*a)-(2*a*b)+(b*b)
ans 1 1
YES
a*b
b*a
ans 9506 9506
YES
1+a-a
b+1-b
ans 1 1
YES
2+1+a+1
1+3+a
ans 101 101
YES
(1+a+b)+7 +c+(d)
a+c+b+d +1+1+(1+(2+3))
ans 402 402
YES
((((1)+a)+b))+6 +c+(d)
a+c+b+d +1+1+(1+(2+3))
ans 401 402
NO