题目描述
对于1 位二进制变量定义两种运算:
运算的优先级是:
先计算括号内的,再计算括号外的。
“× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算。例如:计算表达式A⊕B × C时,先计算 B × C,其结果再与 A 做⊕运算。
现给定一个未完成的表达式,例如+(*_),请你在横线处填入数字0 或者1 ,请问有多少种填法可以使得表达式的值为0 。
【题目分析】
递推
【代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int mod=10007;
struct node{int one,zer;}unit,next;
node num[100010];
char sym[100010],s[100010];
int i,cnt=0,p=0,l=0;
void push()
{sym[++p]=s[i];}
void pop()
{
switch (sym[p--])
{
case'+':
next.one=(num[p].one*num[p+1].one+num[p].zer*num[p+1].one+num[p].one*num[p+1].zer)%mod;
next.zer=(num[p].zer*num[p+1].zer)%mod;
num[p]=next;
break;
case'*':
next.zer=(num[p].zer*num[p+1].zer+num[p].zer*num[p+1].one+num[p].one*num[p+1].zer)%mod;
next.one=(num[p].one*num[p+1].one)%mod;
num[p]=next;
break;
}
}
bool can()
{
if (s[i]=='+'&&sym[p]!='(') return 1;
if (s[i]=='*'&&sym[p]!='('&&sym[p]!='+') return 1;
return false;
}
int main()
{
unit.one=unit.zer=1;
scanf("%d",&l);
scanf("%s",s+1);
sym[++p]='(';
l++;
s[l]=')';
// printf("%s",s+1);
i=1;
while (i<=l)
{
while (s[i]=='(') {push(); i++;}
num[p]=unit;
do
{
if (s[i]==')')
{
while (sym[p]!='(') pop();
p--;
num[p]=num[p+1];
}
else
{
while (can()) pop();
push();
}
i++;
}while(i<=l&&s[i-1]==')');
}
printf("%d\n",num[0].zer);
}