P1691式的取值时间: 1000ms /空间: 131072KiB/Java类名: Main背景下的全国信息学奥林匹克联赛“NOIP2011”复赛普及组第四题中,1位
运算符规则
00=0
01=1
10=1
11=1
00=0
01=0
10=0
11=1
运算的优先顺序如下。
1 .先计算括号内的,再计算括号外的。
2.“”运算优先于“”运算。 也就是说,计算公式时,先计算运算后再计算运算。
例如,在计算式ABC时,首先计算BC,将其结果与a进行运算。
现在指定未完成的表达式,如_ (_*_ )。 请在横线上填写数字0或1。 有多种方法填写公式值为0?
输入格式输入文件名为exp.in,共两行。
第1行是整数l,表示从给定的公式中除去横线后的运算符和括号的个数。
第二个行为第一个字符只包含“”、“”、“”和“*”四种字符,其中“”、“”和“*”是左右括号,“”和“*”分别表示前面定义的运算符“”和“” 此行中的字符按顺序列出了从给定表达式中删除变量后的运算符和括号。
输出格式输出文件exp.out共有一行。 包含表示所有方案数的整数。 注意:这个数量可能很大,
请输出提案数为10007时模拟的结果。
测试示例1输入4
(* )输出3备注【输入输出样品说明】
指定的表达式包含水平线字符,_ (_*_ )
在横线位置填写(0、0、0 )、(0、1、0 )、(0、0、1 )时,公式的值均为0,因此共有三种填写方法。
【数据范围】
对于20%的数据有0L10。
对于50%的数据,有0l1,000。
对于70%的数据,有0l10,000。
对于100%的数据,有0l100,000。
50%的数据输入表达式不包含括号。
Bywjy分析: k0表示值为0的情况数,k1表示值为1的情况数,则:
0 )公式a ) b值为0的情况数) ka0*kb0
公式a * b的值为0的情况数: ka0*kb0 ka1*kb0 ka0*kb1
值为1 )公式a ) b的值为1的情况数) ka0 kb1 ka1*kb0 ka1*kb1
公式a*b的值为1的情况数: ka1*kb1
本问题的想法与求出公式的值相同,但是在数字堆栈中存储了值为0的情况下数量和值为1的情况下数量。
代码:
# include cstdio # include cstring # define maxn 100000 # define mod 10007 usingnamespacestd; char ss[maxn 100],s[maxn 100]; int l,top,a[maxn 100],b[maxn 100]; void add () { int k,k0,k1; k=a[0]; k0=a[k-1]*a[k]; k1=a [ k-1 ] * b [ k ] b [ k-1 ] * a [ k ] b [ k-1 ] * b [ k ]; a[–a[0]]=k0%mod,b[a[0]]=k1%mod; }void multiply () { int k,k0,k1; k=a[0]; k0=a [ k-1 ] * a [ k ] a [ k-1 ] * b [ k ] b [ k-1 ] * a [ k ]; k1=b[k-1]*b[k]; a[–a[0]]=k0%mod,b[a[0]]=k1%mod; (}int main ) ) { int i,j,k; char tmp; scanf(‘%d%s(n ),l,ss ); a[0]=b[0]=top=0; for(I=0; il; I ) { tmp=ss[i]; 开关(tmp ) case ) ) :s[top]=tmp; 布雷克; case”:{if(I==0|(I0ss[I-1]!=’ (() ) ) ) ) a[0]=1,b[a[0]]=1; while(top0s[top]!=’ ‘ () if ) s[top]==’ ‘ ) (添加); else multiply (; 头条- -; } s[ top]=tmp; 布雷克; }case’*’:{if((I0ss[I-1]!=’ () )|| i==0) a[0] )=1,b[a[0] )=1; wile(top0s[top]==’* ‘ )多点)、top–; s[ top]=tmp; 布雷克; }default:{if(ss[I-1]!=’ () ) a[0] )=1,b[a[0] )=1; while(s[top]!=’ ‘ () if ) s[top]==’ ‘ ) (添加); else multiply (; 头条- -; } top–; 布雷克; }}if(top0ss[L-1]!=’ () ) a[0] )=1,b[a[0] )=1; wile(top0) if ) s[top]==’ ‘ ) add ); else multiply (; 头条- -; (if ) l==0) printf ) ‘ %d\n ‘,1 ); ELSEprintf(‘%d\n ‘,a[a[0]] ); 返回0; }