大意:感觉题目没怎么说明白啊,就说题目没说的吧,可能会出现多出一个括号的情况,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); } }