标签:大于 括号 display code nbsp i++ 优先 直接 span
题意:给出一些运算符,有优先级区别;我们可以往运算符两边填数字1或者0
让我们找出最后表达式为0的方案数
思路:如果这道题没有运算优先级,就是层层递推
但现在有了优先级,导致我们无法直接递推计算;
我们需要运用一个栈,来处理优先级的问题;
首先我们先定义两个东西 第一个dp【】【】 这就是用来存储方案数的
第二个p【】 这个是用来模拟栈的,popf是模拟栈的大小
因为3个字符就有4个数字,4个字符就有5个数字(不考虑括号)
假如第一个数不是左括号,我们就可以先放一个数 (因为除了左括号外(当然还有右括号,只是不可能出现右括号而已)其他数左右都要有数字)
然后接下来每次遇到一个符号(除左右括号外)我们就填一个数(操作实现就是dp数字多一位)
然后接下来就是处理优先级问题,题目中有+ * ( )这四种符号
假如是遇到+号,因为*号优先级大于+号,所以得把*号的左右的数都先计算出来
所以遇到+号的时候,就进行work()数组,计算出来
假如遇到*号,就直接放进栈
假如遇到(,也是直接放进栈
假如遇到 ),那么我们需要先处理这个括号内的内容
然后最后可能还会剩下一些符号,我们就再将剩下的都给计算完即可
最后表达式内所有数,都会归为一位
所以答案存储在dp【1】【0】;
1 #include<bits/stdc++.h> 2 #define N (100000+5) 3 #define P (10007) 4 using namespace std; 5 int l,f[N][2],popf=0,pop=0; 6 char p[N],a[N],ch; 7 void push() 8 { 9 popf++; 10 f[popf][0]=1; 11 f[popf][1]=1; 12 } 13 void push(char x){ 14 pop++;p[pop]=x; 15 } 16 void work(char c){ 17 int x=f[popf][0],y=f[popf][1]; 18 int p=f[popf-1][0],q=f[popf-1][1]; 19 popf--; 20 if(c==‘+‘){ 21 f[popf][0]=(x*p)%P; 22 f[popf][1]=(x*q+y*p+y*q)%P; 23 } 24 if(c==‘*‘){ 25 f[popf][0]=(x*p+x*q+y*p)%P; 26 f[popf][1]=(y*q)%P; 27 } 28 } 29 int main() 30 { 31 scanf("%d%s",&l,a); 32 if(a[0]!=‘(‘)push(); 33 for(int i=0;i<l;i++){ 34 ch=a[i]; 35 if(ch==‘+‘){ 36 char c=p[pop]; 37 while(c==‘*‘) 38 {work(c);pop--,c=p[pop];} 39 push(ch); 40 if(a[i+1]!=‘(‘) 41 push(); 42 } 43 else if(ch==‘(‘){ 44 push(ch); 45 if(a[i+1]!=‘(‘) 46 push(); 47 } 48 else if(ch==‘*‘){ 49 push(ch); 50 if(a[i+1]!=‘(‘) 51 push(); 52 } 53 else if(ch==‘)‘){ 54 char c=p[pop]; 55 while(c!=‘(‘){ 56 work(c); 57 pop--; 58 c=p[pop]; 59 } 60 pop--; 61 } 62 } 63 while(pop){ 64 work(p[pop]); 65 pop--; 66 } 67 cout<<f[1][0]; 68 return 0; 69 }
借鉴自:https://www.luogu.com.cn/user/119261
标签:大于 括号 display code nbsp i++ 优先 直接 span
原文地址:https://www.cnblogs.com/pangbi/p/12597625.html