POJ 1472 Instant Complexity(大模拟 判断程序执行次数)

POJ 1472

题目大意

只含4个语句BEGIN, END, LOOP OP和数字,让你判断一共操作多少次,结果以多项式的形式输出.

分析

对于一些模拟题先手动模拟一下就会发现规律,我们可以把LOOP语句看成前括号,END语句看成后括号,这样这道题就和模拟带括号的算数差不多了。
我们可以用一个栈来进行操作,遇见LOOP k就把k进栈在把前括号”(“进栈,遇见OP k就把k进栈,遇见END把“)”进栈。
最后的问题就是把这个栈序列转化成答案的形式了

一开始RE后面发现是数组开下了,改了后TLE,以后一定要注意字符串很多的不要用string,又改了后WA,-_-||
评测系统是测试到某个地方发现某种类型的错误就立即返回
最后是因为次数是1和0的时候的一个细节出了问题

总结

对于这种对细节需要特别注意的题,如果在WA了之后的debug方法一般是先查一下代码有没有逻辑错误,实在找不出了就手动多造几组数据,比赛的时候在写时候就让队友先造一些数据多考虑一下边界条件

代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<stack>
using namespace std;
int num[15][15];//表达式
int cnt=0;
stack<int> St;//St中-100表示n ;-20表示前括号;-1到-10表示num[1]到num[10];
int To_int(char s[])
{
      int ans=0;
      int len=strlen(s);
      for(int i=0;i<len;i++) ans=ans*10+(int)s[i]-(int)'0';
      return ans;
}
void Update()//栈中进了一个后括号引发的更新操作
{
    int x;
    cnt++;
    while(1)
    {
        x=St.top();
        St.pop();
        if(x==-20)//遇见前括号退出
        {
             x=St.top();
             St.pop();
             if(x>=0)
                   for(int i=0;i<=10;i++)num[cnt][i]=x*num[cnt][i];
             else if(x==-100)//遇见n
             {
                   for(int i=10;i>=1;i--)num[cnt][i]=num[cnt][i-1];
                   num[cnt][0]=0;
             }
             St.push(-cnt);
             break;
        }
        else if(x>=0) num[cnt][0]+=x;
        else if(x<0)//遇见表达式
        {
             for(int i=0;i<=10;i++)num[cnt][i]+=num[-x][i];
        }
    }
}
void Print_ans()
{
    printf("Runtime = ");
    int x=St.top();
    x=-x;
    //判断是否为0
    int bj=0;
    for(int i=0;i<=10;i++)if(num[x][i]!=0)bj=1;
    if(bj==0){printf("0\n");return ;}

    int flag=0;//flag==1则需要输+号
    for(int i=10;i>=0;i--)
    {
         if(num[x][i]==0)continue;
         if(flag==1)printf("+");
         if(num[x][i]!=1)
         {
             if(i>1)printf("%d*n^%d",num[x][i],i);
             else if(i==1)printf("%d*n",num[x][i]);
             else if(i==0)printf("%d",num[x][i]);
         }
         else if(num[x][i]==1)
         {
             if(i>1)printf("n^%d",i);
             else if(i==1)printf("n");
             else if(i==0)printf("1");
         }

         flag=1;
    }
    printf("\n");
}
void Work()
{
      char s[100];
      scanf("%s",s);//输入BEGIN
      int bj=0;//未配对的END数目
      while(!St.empty())St.pop();//清空栈
      St.push(1);
      St.push(-20);//BEGIN对应的前括号进栈
      while(1)
      {
            scanf("%s",s);
            if(s[0]=='L')
            {
                  bj--;
                  scanf("%s",s);
                  if(s[0]=='n')St.push(-100);//-100表示n
                  else St.push(To_int(s));
                  St.push(-20);//前括号进栈
            }
            else if(s[0]=='E')
            {
                  bj++;
                  if(bj==1)break;//BEGIN对应的END
                  Update();
            }
            else if(s[0]=='O')
            {
                 scanf("%s",s);
                 St.push(To_int(s));
            }
      }
      Update();
}
void Init()
{
      cnt=0;
      memset(num,0,sizeof(num));
}
int main()
{
    int T;

    scanf("%d",&T);
    int Case=0;
    while(T--)
    {
         Init();
         Work();
         printf("Program #%d\n",(++Case));
         Print_ans();
         printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值