poj1472

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

 

[cpp]  view plain copy
  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. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值