普及组exp解题报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

普及组exp的解题报告

南京树人国际学校徐韧喆

【题目描述】

对于1 位二进制变量定义两种运算:

运算符运算规则

⊕0⊕0=0

0⊕1=1

1⊕0=1

1⊕1=1

×0×0=0

0×1=0

1×0=0

1×1=1

运算的优先级是:

1. 先计算括号内的,再计算括号外的。

2. “×”运算优先于“⊕”运算,即计算表达式时,先计算×运算,再计算⊕运算。例如:计算表达式A⊕B ×C时,先计算B ×C,其结果再与A 做⊕运算。

现给定一个未完成的表达式,例如_+(_*_),请你在横线处填入数字0 或者1 ,请问

有多少种填法可以使得表达式的值为0 。

【输入】

输入文件名为exp.in ,共2 行。

第1 行为一个整数L,表示给定的表达式中除去横线外的运算符和括号的个数。

第2 行为一个字符串包含L 个字符,其中只包含’(’、’)’、’+’、’*’这4 种字符,其中’(’、’)’是左右括号,’+’、’*’分别表示前面定义的运算符“⊕”和“×”。这行字符按顺序

给出了给定表达式中除去变量外的运算符和括号。

【输出】

输出文件exp.out 共1 行。包含一个整数,即所有的方案数。注意:这个数可能会很大,请输出方案数对10007 取模后的结果。

【样例】

exp.in

4

+(*)

exp.out

3

【数据范围】

对于20% 的数据有0 ≤L ≤10。

对于50% 的数据有0 ≤L ≤1,000。

对于70% 的数据有0 ≤L ≤10,000 。

对于100%的数据有0 ≤L ≤100,000。

对于50% 的数据输入表达式中不含括号。

【问题分析】

这是一道表达式计算的扩展题,对选手最基本的要求就是表达式计算。在一般的表达式计算中,存放结果的栈都是记录计算到某一步的结果,而在这道题中,结果只可能为2个(0或者1),且是知道的,而运算的数字是不一定的,所以在栈中只需存放算到0或者1时的方案数,最后输出到最后算出0的方案数即可。

【算法实现】

一、

首先粗略地说一下表达式计算的方法:

需要使用两个栈,一个存放结果,另一个存放符号。每次读入一个数据,就进入结果栈,如果是符号,则按以下方法:

1、如果是左括号,就直接进栈;

2、如果是右括号,就一直弹栈并加以计算,直到弹到左括号;

3、如果是运算符,则弹栈,直到这个运算符的优先级大于符号栈栈顶的符号的优先级

或是左括号或栈空,然后将运算符进栈;

最后再将栈中残余的符号和结果一直弹到只剩一个结果,这个就是最后的结果。

二、

此题算法的框架整体上是和表达式计算相同的,有以下几个方面不同:

1、需要添加数字的地方应该满足不在右括号的后面或者左括号的前面

2、优先级:“*”的优先级比“+”高

3、运算方法,每一步计算为0或1的方法数:设两个步骤的运算结果经过每个符号到一个结果时,第一个运算结果算出0的方案数为t1,1的方案数为t2,第二个算出0的方案数为t3,算出1的方案数为t4,则有:

当符号是“⊕”时,得到0的方案数为t1*t3,1的方案数:t1*t4+t2*t3+t2*t4

当符号是“×”时,得到0的方案数为t1*t3+t1*t4+t2*t3,1的方案数:t2*t4

用一个栈记录下来即可。

【程序实现】

var str:ansistring;

nn,n,i,top1,top2,kk:longint;

ans1,ans2:array[1..200000] of longint;

fu:array[1..200000] of char;

procedure suan(top1,top2:longint); {计算每一步的方案数}

var t1,t2,t3,t4:longint;

begin

t1:=ans1[top1];t2:=ans2[top1];

t3:=ans1[top1+1];t4:=ans2[top1+1];

if fu[top2]='+' then

begin

ans1[top1]:=t1*t3 mod 10007;

ans2[top1]:=(t1*t4+t2*t4+t2*t3) mod 10007;

end

else

begin

ans1[top1]:=(t1*t3+t1*t4+t2*t3) mod 10007;

ans2[top1]:=t2*t4 mod 10007;

end;

end;

function jisuan(ch:char):longint; {计算优先级}

begin

case ch of

'#','(':jisuan:=0;

'+':jisuan:=1;

'*':jisuan:=2;

end;

end;

begin

assign(input,'exp.in');

assign(output,'exp.out');

reset(input);

rewrite(output);

readln(n);

readln(str);

top1:=0;

fu[1]:='#';

top2:=1;

if str[n]<>')' then nn:=n+1 else nn:=n;

for i:=1 to nn do {表达式运算的过程}

begin

if (i=n+1) or (((i=1) or (str[i-1]<>')')) and (str[i]<>'(')) then begin

inc(top1);

ans1[top1]:=1;

ans2[top1]:=1;

end;

if i<>n+1 then

if str[i]='(' then

begin

inc(top2);

fu[top2]:='(';

end

else

if str[i]=')' then

begin

while fu[top2]<>'(' do

begin

suan(top1-1,top2);

dec(top1);

dec(top2);

end;

相关文档
最新文档