[https://www.luogu.com.cn/problem/P1310]([NOIP2011 普及组] 表达式的值)
神仙题, 被吊着打qaq
这不就是一个求表达式树的后序遍历吗. \(—zwd\)
水题。 水题。 虐了我两次。 qaq
然后就开始了表达式的恶补
首先是把表达式转成后缀表达式 因为好求
转的方法:
-
如果有数字 直接放在后缀表达式中
-
如果是运算符 把运算符低于他的运算符加入表达式中, 并出栈, 再把这个运算符放入栈
-
有括号的情况就是把括号里的全部放进去
怎么求
我们可以按顺序扫描整个字符串, 发现一个数字就放入数字栈, 发现一个运算符取出数字栈栈顶的两个数, 进行运算, 压入数字栈
我们这道题是要自己补数字, dp
数组记的是第i
个位置0
有多少种可能1
有多少种可能, 按表达式求值算就行了
#include <bits/stdc++.h>
using namespace std;
#define Mod 10007
#define int long long
const int N= 200005;
char stk[N], ans[N], num[N];
int top, tot, cnt;
int dp[N][2];
signed main()
{
int n; cin>> n;
string s; cin>> s;
ans[++ tot]= '_';
for(int i=0; i<s.size(); i++)
{
if(s[i]== '*'|| s[i]== '(') stk[++ top]= s[i];
else if(s[i]== '+')
{
while(stk[top]== '*') ans[++ tot]= stk[top-- ];
stk[++ top]= s[i];
}
else if(s[i]== ')')
{
while(stk[top]!= '(') ans[++ tot]= stk[top-- ];
top-- ;
}
if(s[i]!= '('&& s[i]!= ')') ans[++ tot]= '_';
}
while(top) ans[++ tot]= stk[top-- ];
for(int i=1; i<=tot; i++)
{
if(ans[i]== '_')
{
dp[++ cnt][0]= 1; dp[cnt][1]= 1; //不能连等!!!!
continue;
}
if(ans[i]== '*')
{
dp[cnt- 1][0]= dp[cnt- 1][0]* (dp[cnt][0]+ dp[cnt][1])% Mod+ dp[cnt- 1][1]* dp[cnt][0]% Mod;
dp[cnt- 1][1]= dp[cnt- 1][1]* dp[cnt][1]% Mod;
}
else
{
dp[cnt- 1][1]= dp[cnt- 1][1]* (dp[cnt][0]+ dp[cnt][1])% Mod+ dp[cnt- 1][0]* dp[cnt][1]% Mod;
dp[cnt- 1][0]= dp[cnt- 1][0]* dp[cnt][0]% Mod;
}
cnt-- ;
}
cout<< dp[1][0]% Mod<< endl;
return 0;
}
/*
5
***+*
*/