POJ1472Instant Complexity

转载请注明出处:優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

  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再处理。

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 }
Sample Input
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
 
 
Sample Output
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
[ EXP技术分享博客 ] 版权所有,转载请注明出处: http://exp-blog.com
原文地址:https://www.cnblogs.com/lyy289065406/p/2122852.html