NOIPDay1T2时间复杂度

NOIPDay1T2时间复杂度

题目描述
小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正确。
A++语言的循环结构如下:
F i x y
    循环体
E
其中F i x y表示新建变量 
ii
i(变量 
ii
i 不可与未被销毁的变量重名)并初始化为 
xx
x, 然后判断 
ii
i 和 
yy
y 的大小关系,若 
ii
i 小于等于 
yy
y 则进入循环,否则不进入。每次循环结束后 
ii
i 都会被修改成 
i+1i +1
i+1,一旦 
ii
i 大于 
yy
y 终止循环。
xx
x 和 
yy
y 可以是正整数(
xx
x 和 
yy
y 的大小关系不定)或变量 
nn
n。
nn
n 是一个表示数据规模的变量,在时间复杂度计算中需保留该变量而不能将其视为常数,该数远大于 100。
“E”表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。
注:本题中为了书写方便,在描述复杂度时,使用大写英文字母“O”表示通常意义下“Θ”的概念。
输入输出格式
输入格式:

输入文件第一行一个正整数 
tt
t,表示有 
tt
t(
t≤10t \le 10
t≤10)个程序需要计算时间复杂度。 每个程序我们只需抽取其中 F i x y和E即可计算时间复杂度。注意:循环结构 允许嵌套。
接下来每个程序的第一行包含一个正整数 
LL
L 和一个字符串,
LL
L 代表程序行数,字符 串表示这个程序的复杂度,O(1)表示常数复杂度,O(n^w)表示复杂度为
nwn^w
n
w
,其 中w是一个小于100的正整数(输入中不包含引号),输入保证复杂度只有O(1)和O(n^w) 两种类型。
接下来 
LL
L 行代表程序中循环结构中的F i x y或者 E。 程序行若以F开头,表示进入一个循环,之后有空格分离的三个字符(串)i x y, 其中 
ii
i 是一个小写字母(保证不为
nn
n),表示新建的变量名,
xx
x 和 
yy
y 可能是正整数或 
nn
n ,已知若为正整数则一定小于 100。
程序行若以E开头,则表示循环体结束。

输出格式:

输出文件共 
tt
t 行,对应输入的 
tt
t 个程序,每行输出Yes或No或者ERR(输出中不包含引号),若程序实际复杂度与输入给出的复杂度一致则输出Yes,不一致则输出No,若程序有语法错误(其中语法错误只有: ① F 和 E 不匹配 ②新建的变量与已经存在但未被销毁的变量重复两种情况),则输出ERR 。
注意:即使在程序不会执行的循环体中出现了语法错误也会编译错误,要输出 ERR。

输入输出样例
输入样例#1: 复制 
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
输出样例#1: 复制 
Yes
Yes
ERR
Yes
No
Yes
Yes
ERR
说明
【输入输出样例解释1】
第一个程序 
ii
i 从 11 是常数复杂度。
第二个程序 
xx
x 从 1 到 
nn
n 是 
nn
n 的一次方的复杂度。
第三个程序有一个 F 开启循环却没有 E 结束,语法错误。
第四个程序二重循环,
nn
n 的平方的复杂度。
第五个程序两个一重循环,
nn
n 的一次方的复杂度。
第六个程序第一重循环正常,但第二重循环开始即终止(因为
nn
n远大于100100大于4)。
第七个程序第一重循环无法进入,故为常数复杂度。
第八个程序第二重循环中的变量 
xx
x 与第一重循环中的变量重复,出现语法错误②,输出 ERR。
【数据规模与约定】
对于 30%的数据:不存在语法错误,数据保证小明给出的每个程序的前 
L/2L/2
L/2 行一定为以 F 开头的语句,第 
L/2+1L/2+1
L/2+1 行至第 
LL
L 行一定为以 
EE
E 开头的语句,
L≤10L \le 10
L≤10,若 
xx
x、
yy
y 均 为整数,
xx
x 一定小于 
yy
y,且只有 
yy
y 有可能为 
nn
n。
对于 50%的数据:不存在语法错误,
L≤100L \le 100
L≤100,且若 
xx
x、
yy
y 均为整数,
xx
x 一定小于 
yy
y, 且只有 
yy
y 有可能为 
nn
n。
对于 70%的数据:不存在语法错误,
L≤100L \le 100
L≤100。
对于 100%的数据:
L≤100L \le 100
L≤100

直接模拟即可

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cmath>
#include <stack>
#include <set>
using namespace std;
const int M = 10;
const int INF = 1e9;

char O[M], tip[M], x[M], y[M], per[M];      //时间复杂度 
int L;          //程序的行数 

set<char> have;
stack<char> stacks;
stack<char> stacks2;

int main()
{
    freopen("in.txt", "r", stdin);
    int T;
    scanf("%d", &T);
    while (T--) {
      have.clear(); 
      while (!stacks.empty()) stacks.pop();
      while (!stacks2.empty()) stacks2.pop();
      memset(O, 0, sizeof O);
      scanf("%d%s", &L, O);
      int res0 = 0;
      for (int i = 0; O[i]; ++i)
        if (O[i] == '(') {
          if (O[i+1] == '1')
            res0 = 0;
          else
            for (int j = i + 3; O[j] != ')'; ++j)
              res0 = res0*10 + O[j] - '0'; 
        }
      int level = 0;        //当前是第几层循环 
      int maxLevel = 0;     //最大有几层循环
      bool open = true;
      bool flag = true;
      char key;
      for (int i = 1; i <= L; ++i) {
        scanf("%s", tip);
        if (tip[0] == 'F') {
          scanf("%s%s%s", per, x, y);
          //已经错误 
          if (flag == false) continue;
          //插入一个未销毁的变量 
          if (have.count(per[0])) {
            flag = false;
            continue;
          }
          else {
            have.insert(per[0]);
            stacks.push(per[0]);
          }
          if (open == false) continue;//当前的循环不执行,但需要判断是否合法
          int left = 0, right = 0;
          if (x[0] >= '0' && x[0] <= '9')
            for (int j = 0; x[j]; ++j)
              left = left * 10 + x[j] - '0';
          else left = INF;
          if (y[0] >= '0' && y[0] <= '9')
            for (int j = 0; y[j]; ++j)
              right = right * 10 + y[j] - '0';
          else right = INF;
          if (left < right && right == INF) {
            ++level;
            stacks2.push(per[0]);
          }
          if (left > right) open = false, key = per[0];
          maxLevel = max(maxLevel, level);
        }
        else {
          if (flag == false) continue; 
          if (stacks.size() == 0) {
            flag = false;
            continue;
          }
          char now = stacks.top();
          stacks.pop();
          have.erase(now);
          if (stacks2.size() && stacks2.top() == now) {
            --level;
            stacks2.pop();
          }
          if (open == false && key == now) open = true;
        }
      }
      if (flag == false || stacks.size()) {
        printf("ERR\n");
        continue;
      }
      if (maxLevel == res0) printf("Yes\n"); 
      else printf("No\n");
    }
    return 0;   
} 
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页