时间复杂度

本文介绍了一个编程问题,要求编写程序验证小明用A++语言编写的程序中关于循环时间复杂度的判断是否正确,涉及对循环结构的理解和时间复杂度分析。
摘要由CSDN通过智能技术生成

 题目描述

小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正确。

A++语言的循环结构如下:

F i x y
    循环体
E

 
其中`F i x y`表示新建变量 (变量 i 不可与未被销毁的变量重名)并初始化为 x, 然后判断 i 和 y 的大小关系,若 i 小于等于 y 则进入循环,否则不进入。每次循环结束后 i 都会被修改成 i+1,一旦 i 大于 y 终止循环。

x 和 y 可以是正整数(x 和 y 的大小关系不定)或变量 n。n 是一个表示数据规模的变量,在时间复杂度计算中需保留该变量而不能将其视为常数,该数远大于 100。

`E` 表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。

注:本题中为了书写方便,在描述复杂度时,使用大写英文字母 O 表示通常意义下 O 的概念。

输入样例

8
2 O(1)
F i 1 1
E
2 O(n^1)
F x 1 n
E
1 O(1)
F x 1 n
4 O(n^2)
F x 5 n
F y 10 n
E
E
4 O(n^2)
F x 9 n
E
F y 2 n
E
4 O(n^1)
F x 9 n
F y n 4
E
E
4 O(1)
F y n 4
F x 9 n
E
E
4 O(n^2)
F x 1 n
F x 1 10
E
E

输出样例

Yes
Yes
ERR
Yes
No
Yes
Yes
ERR

AC代码:

//时间复杂度
#include <bits/stdc++.h>
using namespace std;

int t,L,ans;
struct Code
{
  char F,i;
  int x,y;
} code[200];

int Judge()
{
  stack <int> st;
  int used[256]= {0};
  int time=0,Maxtime=0,stop=0;   //stop是无法进入循环的标志
  for(int i=0; i<L; i++)
    if(code[i].F=='F')
    {
      if(used[code[i].i])        //如果重复定义变量,返回-1
        return -1;
      used[code[i].i]=1;         //变量被使用,标记
      st.push(i);                //代码行数编号入栈
      if(code[i].y-code[i].x<0)  //如不能循环,那么下面嵌套的循环都无效
        stop++;
      if(code[i].y-code[i].x>1e6 && !stop)
        time++;                  //进入n的循环,贡献时间复杂度
      Maxtime=max(Maxtime,time); //更新最大时间复杂度
    }
    else
    {
      if(st.empty())
        return -1;
      used[code[st.top()].i]=0;  //变量被销毁,取消标记
      if(code[st.top()].y-code[st.top()].x>1e6 && !stop)
        time--;
      if(code[st.top()].y-code[st.top()].x<0)
        stop--;
      st.pop();
    }
  return st.size()==0?Maxtime:-1;
}

int main()
{
  // freopen("complexity.in","r",stdin);
  // freopen("complexity.out","w",stdout);
  cin>>t;
  while(t--)
  {
    scanf("%d",&L);             //获取代码行数
    string S,X,Y;
    getline(cin,S);             //获取时间复杂度,注意S开头有一个空格
    int Time=S[3]=='1'?0:(S.size()==7  ? S[5]-'0' : (S[5]-'0')*10+S[6]-'0');

    for(int i=0; i<L; i++)
    {
      cin>>code[i].F;
      if(code[i].F=='F')
      {
        cin>>code[i].i>>X>>Y;
        code[i].x=(X=="n"?1e8:atoi(X.c_str()));//string转char用c_str()
        code[i].y=(Y=="n"?1e8:atoi(Y.c_str()));//atoi将*char转为整数
      }
    }
    int ans=Judge();
    ans==-1?printf("ERR\n"):printf("%s\n",ans==Time?"Yes":"No");
  }
  return 0;
}

运行结果

 

完结撒花✿✿ヽ(°▽°)ノ✿ 

(前年有一个人赞了我,他娶了年轻貌美的女朋友。 去年,另一个人赞了我,他中了900万。 今年,赞了我的人都娶了年轻貌美的姑娘结婚那天中了900万。 别说我不够意思,话已经放这里了,能不能把握就要看你们自己了。 。。)

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值