Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 2017 | Accepted: 698 |
Description
< Program > ::= "BEGIN" < Statementlist > "END" < Statementlist > ::= < Statement > | < Statement > < Statementlist > < Statement > ::= < LOOP-Statement > | < OP-Statement > < LOOP-Statement > ::= < LOOP-Header > < Statementlist > "END" < LOOP-Header > ::= "LOOP" < number > | "LOOP n" < OP-Statement > ::= "OP" < number >The run-time of such a program can be computed as follows: the execution of an OP-statement costs as many time-units as its parameter specifies. The statement list enclosed by a LOOP-statement is executed as many times as the parameter of the statement indicates, i.e., the given constant number of times, if a number is given, and n times, if n is given. The run-time of a statement list is the sum of the times of its constituent parts. The total run-time therefore generally depends on n.
Input
Output
Sample Input
2BEGIN LOOP n OP 4 LOOP 3 LOOP n OP 1 END OP 2 END OP 1 END OP 17ENDBEGIN OP 1997 LOOP n LOOP n OP 1 END ENDEND
Sample Output
Program #1Runtime = 3*n^2+11*n+17Program #2Runtime = n^2+1997
Source
大致题意:
给出一段Pascial程序,计算其时间复杂度(能计算的项则计算,不能计算则化到最简的关于n的表达式O(n),并把各项根据n的指数从高到低排列),输出时,系数为0的项不输出,系数为1的项不输出系数,指数为1的项不输出指数。
一段程序只有唯一一个BEGIN,代表程序的开始。与其对应的为最后的END,代表程序的结束。
一段程序最多只有10层循环嵌套,循环的入口为LOOP,一个LOOP对应一个END,代表该层循环的结束。
一段程序中OP的个数不限。
LOOP是循环的入口,其后面的数据可能是常量(非负整数),也可能是变量n,代表循环体执行的次数。
OP是语句,其后面的数据只能为常量(非负整数),代表该语句执行的次数。
解题思路:递归+模拟
此题就是一条表达式化简的模拟题,用递归直接模拟。
以第一个样例说明处理方法:
BEGIN
LOOP n
OP 4
LOOP 3
LOOP n
OP 1
END
OP 2
END
OP 1
END
OP 17
END
从该例子我们可以得到一条关于n的最初表达式:
n*(4+3*(n*1+2)+1)+17
稍微化简一下,合并同一层的OP值,得到了
n*(3*(n*1+2)+5)+17
不难看出每一个循环体都能写成k*n+i形式的子表达式,其中loop是*关系,op是+关系
由于最大循环次数为10,那么我们用exp[11]存储多项式的每一项的指数i和系数k=exp[i],其中exp[0]其实就是常数项,由OP语句产生
注意LOOP后面可能输入字符n,也可能输入数字,处理方法:用字符串输入s,若为s[0]==n,则直接作字符处理;若s[0]!=n,则认为是数字串,把它转换为int再处理。
AC代码:
#include#include using namespace std;char ch[10];int deal(int *exps){ scanf("%s",ch); if(ch[0]=='E') return 0; if(ch[0]=='B') while(deal(exps)); else if(ch[0]=='L'){ int t=-1,texps[11]={ 0}; scanf("%s",ch); if(ch[0]!='n') t=atoi(ch); while(deal(texps)); if(t==-1){ for(int i=10;i>=1;i--) texps[i]=texps[i-1]; texps[0]=0; } else for(int i=0;i<=10;i++) texps[i]*=t; for(int i=0;i<=10;i++) exps[i]+=texps[i]; } else{ scanf("%s",ch); exps[0]+=atoi(ch); return deal(exps); } return 1;}int main(){ int n,t; scanf("%d",&n); for(int i=1;i<=n;i++){ int exps[11]={ 0};t=0; deal(exps); printf("Program #%d\nRuntime = ", i); for(int j=10;j>=0;j--){ if(exps[j]){ t++; if(t!=1) printf("+"); if(exps[j]!=1||j==0)printf("%d", exps[j]); if(exps[j]!=1&&j>0)printf("*"); if(j>1)printf("n^%d", j); if(j==1)printf("n"); } } if(!t) printf("0"); printf("\n\n"); } return 0;}