大意:感觉题目没怎么说明白啊,就说题目没说的吧,可能会出现多出一个括号的情况,70%的数据会多一个括号,其中有一个案例卡了我一天,多余的括号是右括号,而且出现在表达式的中间,我是用递归写的,解
这样的式子我的代码会出问题(大部分人是用递归写的,目测这个案例左括号
右边乘的是1,因为有人没有特判是否有左括号与当前的右括号匹配,导致运算符栈内元素个数为-1,然后他
的解为3(数字栈中有两个数,都是3,但运算符栈内元素个数为0,所以运算结束,输出栈底的元数),但是却a了,数据水~)
所以注意一下 1+2)*3 这组数据就好了
思路:先把空格消除,然后给a赋值为一个特殊的质数(随便也行),然后运算时模一个大点的质数,接下来不就是《表达式求值4》吗,直接复制《表达式求值4》的代码然后特判多出一个右括号的情况,就可以了。更保险的是每组表达式给a赋多个数,然后比较。
if(cnt<0) {
s='('+s;
return deal(l,r+1);
}//多出一个')' Code:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int mod=1e9+7;
string s;
ll chang(int l,int r) {
ll ans=0;
if(s[l]=='a') return (ll)13;
for(int i=l;i<=r;++i)
ans=(ans*10+(s[i]-48))%mod;
return ans;
}
ll qpow(ll a,ll b) {
ll ans=1;
while(b) {
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
ll deal(int l,int r) {
int cnt=0,aos=-1,pos=-1,cf=-1;
for(int i=l;i<=r;++i) {
if(s[i]=='(') {
++cnt;
continue;
}
if(s[i]==')') {
--cnt;
continue;
}
if(cnt==0) {
if(s[i]=='+'||s[i]=='-') aos=i;
else if(s[i]=='*') pos=i;
else if(s[i]=='^') cf=i;
}
}
if(cnt>0&&s[l]=='(') return deal(l+1,r);
if(cnt<0&&s[r]==')') return deal(l,r-1);
if(cnt<0) {
s='('+s;
return deal(l,r+1);
}
if(s[l]=='('&&s[r]==')'&&aos==-1&&pos==-1&&cf==-1) return deal(l+1,r-1);//shch as:((12))
if(aos>0) {
if(s[aos]=='+')
return (deal(l,aos-1)+deal(aos+1,r))%mod;
else
return (deal(l,aos-1)-deal(aos+1,r)+mod)%mod;
}
else if(pos>0)
return deal(l,pos-1)*deal(pos+1,r)%mod;
else if(cf>0)
return qpow(deal(l,cf-1),deal(cf+1,r));
return chang(l,r);
}
void deleteAllMark(string &s, const string &mark) {
size_t nSize = mark.size();
while(1) {
size_t pos = s.find(mark);
if(pos == string::npos) return;
s.erase(pos, nSize);
}
}
int main() {
ll ans,ans1,n;
cin.tie(0);cout.tie(0);
getline(cin,s);
deleteAllMark(s," ");
ans=deal(0,s.length()-1);
cin>>n;
cin.get();
for(int i=0;i<n;++i) {
getline(cin,s);
deleteAllMark(s," ");
ans1=deal(0,s.length()-1);
if(ans1==ans) cout<<(char)('A'+i);
}
} 
京公网安备 11010502036488号