转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1308998858
大致题意:
给出一段Pascial程序,计算其时间复杂度(能计算的项则计算,不能计算则化到最简的关于n的表达式O(n),并把各项根据n的指数从高到低排列),输出时,系数为0的项不输出,系数为1的项不输出系数,指数为1的项不输出指数。
一段程序只有唯一一个BEGIN,代表程序的开始。与其对应的为最后的END,代表程序的结束。
一段程序最多只有10层循环嵌套,循环的入口为LOOP,一个LOOP对应一个END,代表该层循环的结束。
一段程序中OP的个数不限。
LOOP是循环的入口,其后面的数据可能是常量(非负整数),也可能是变量n,代表循环体执行的次数。
OP是语句,其后面的数据只能为常量(非负整数),代表该语句执行的次数。
解题思路:
此题就是一条表达式化简的模拟题,用递归直接模拟。
以第一个样例说明处理方法:
BEGIN
OP 4
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再处理。
Source修正:
http://www.informatik.uni-ulm.de/acm/Regionals/1997/
1 //Memory Time
2 //264K 0MS
3
4 #include<iostream>
5 using namespace std;
6
7 /*字符串转数字*/
8 int StrToNum(char* s)
9 {
10 int digit=0;
11 for(int i=0;s[i];i++)
12 digit=digit*10+(s[i]-'0');
13
14 return digit;
15 }
16
17 bool solve(int* exp)
18 {
19 char s[30];
20 cin>>s;
21
22 if(s[0]=='E') //END
23 return false;
24 else if(s[0]=='B') //BEGIN
25 while(solve(exp)); //若因为OP返回,则继续;若因为END返回,则结束
26 else if(s[0]=='O') //0P
27 {
28 cin>>s;
29 exp[0]+=StrToNum(s);
30 return solve(exp);
31 }
32 else //LOOP
33 {
34 int TempExp[11]={0}; //临时exp[]
35 cin>>s;
36 while(solve(TempExp));
37
38 if(s[0]=='n') //LOOP n
39 {
40 for(int i=10;i>0;i--)
41 TempExp[i]=TempExp[i-1]; //表达式乘以n,则所有项的次数+1
42 TempExp[0]=0;
43 }
44 else //LOOP Num
45 {
46 int x=StrToNum(s);
47 for(int i=0;i<11;i++)
48 TempExp[i]*=x; //表达式乘以const,则所有项的系数*const
49 }
50 for(int i=0;i<11;i++)
51 exp[i]+=TempExp[i];
52 }
53 return true;
54 }
55
56 int main(void)
57 {
58 int test;
59 cin>>test;
60 for(int t=1;t<=test;t++)
61 {
62 char s[6];
63 int exp[11]={0}; //指数为i的项,其系数为exp[i]
64
65 solve(exp);
66
67 cout<<"Program #"<<t<<endl;
68 cout<<"Runtime = ";
69
70 bool flag=false;
71 bool before=false; //标记输出当前项之前,是否输出过前面的项
72 for(int i=10;i>=0;i--)
73 if(exp[i]) //当系数不为0时,才输出该项
74 {
75 flag=true;
76
77 if(before)
78 {
79 cout<<'+';
80 before=false;
81 }
82
83 if(!i) //当指数为0时,直接输出系数
84 {
85 cout<<exp[i];
86 before=false;
87 }
88 else
89 {
90 bool sign=false; //标记系数是否为1
91 if(i && exp[i]!=1)
92 {
93 sign=true;
94 cout<<exp[i];
95 before=true;
96 }
97 if(i) //当指数不为0时
98 {
99 if(sign)
100 cout<<'*';
101 cout<<'n';
102 if(i!=1)
103 cout<<'^'<<i;
104 before=true;
105 }
106 }
107 }
108 if(!flag)
109 cout<<0<<endl<<endl;
110 else
111 cout<<endl<<endl;
112 }
113 return 0;
114 }
11
BEGIN
LOOP n
OP 4
LOOP 3
LOOP n
OP 1
END
OP 2
END
OP 1
END
OP 17
END
BEGIN
OP 1997 LOOP n LOOP n OP 1 END END
END
BEGIN
LOOP 0 OP 17 END
END
BEGIN
LOOP n OP 0 END
END
BEGIN
OP 1 LOOP n LOOP n OP 3 LOOP n OP 2 END END END
END
BEGIN
LOOP n OP 1
LOOP n OP 2
LOOP n OP 3
LOOP n OP 4
LOOP n OP 5
LOOP n OP 6
LOOP n OP 7
LOOP n OP 8
LOOP n OP 9
LOOP n OP 10
END END END END END
LOOP 17 LOOP n LOOP n OP 3 END END END
END END END END END
END
BEGIN LOOP 1 LOOP 2 LOOP 3 OP 1 LOOP 4 LOOP 5 LOOP 6 LOOP 7 LOOP 8 OP 1
END END END END OP 2 END END END END OP 17 END
BEGIN OP 1 OP 2 OP 3 OP 4 OP 5 OP 6 OP 7 OP 8 OP 9 OP 10 OP 11 OP 12 END
BEGIN LOOP n LOOP n LOOP n LOOP n LOOP n LOOP n LOOP n LOOP n LOOP n LOOP n
OP 12345 END END END END END END END END END END END
BEGIN OP
17
LOOP 2
LOOP n
LOOP
2 OP
4 LOOP
n OP 4
LOOP n OP 5
END
END OP 4 END
END END
END
BEGIN
OP 0 LOOP n LOOP
n
OP 88 OP 0 LOOP n LOOP 0 OP 17 END END
END END
OP 0 LOOP n LOOP 3 OP 0 END
END OP 8
END
Program #1
Runtime = 3*n^2+11*n+17
Program #2
Runtime = n^2+1997
Program #3
Runtime = 0
Program #4
Runtime = 0
Program #5
Runtime = 2*n^3+3*n^2+1
Program #6
Runtime = 10*n^10+9*n^9+8*n^8+58*n^7+6*n^6+5*n^5+4*n^4+3*n^3+2*n^2+n
Program #7
Runtime = 40391
Program #8
Runtime = 78
Program #9
Runtime = 12345*n^10
Program #10
Runtime = 20*n^3+16*n^2+32*n+17
Program #11
Runtime = 88*n^2+8