题目 时间复杂度【NOIP2017提高组】

题目描述

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

输入格式

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

输出格式

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

思路

  1. 我们需要判断YES/NO/ERR:首先判断ERR存在两种情况F和E不对应,我们可以用spy变量保存目前循环深度,若F即进入一层循环E则退出一层循环,若判断到spy小于或结束判断到spy!=0则说明没有循环退出或有循环没有退出;第二种变量使用重复:我们使用alpha数组维护使用过的变量,ASCII码为下标,用optt数组维护每个循环下的变量,若退出第i层循环则alpha[optt[i]] = false。
  2. F语句中有三种情况:x=y;x=n&&y!=n;x!=n&&y=n;x<y;若x=y则对时间复杂度没有贡献spy++进入下一层,若x!=n&&y=n则当前时间复杂度h+1且记录当前循环Ois[spy]=1,若x=n&&y!=n||x<y那么不能进入下一层enter=1,且记录level=spy
  3. E语句更新ans,销毁当前循环变量,判断有没有ERR,更新状态。

代码

#include<bits/stdc++.h>
using namespace std;typedef long long ll;
typedef pair<int, int> PII;
const int N = 110;int t, n, state, ii;//t:test数量 n:行数 state:0-NO 1-YES 2-ERR
int Oi, ans, spy;//存储复杂度 0为常数复杂度 >0 为 n^Oi   判断当前是否处于循环
int optt[N];// optt每个循环下的变量
int Ois[N]; // 存储复杂度变化
char opt[N];//opt为每个F/E
string buff;
string varN[N], sta[N], en[N];//存储E/F, 变量名字,起始,结束
bool alpha[123]; //存储当前没销毁的变量ASCIIint getfS(string temp,int pos) {//pos=1 数字->数字 pos=2 char->数字int res = 0;if (pos == 2) return (int)temp[0];for (int i = 0; i < temp.length(); i++) {if (temp[i] >= '0' && temp[i] <= '9') {res *= 10;res += temp[i] - '0';}}return res;
}
int main() {cin.tie(0);ios::sync_with_stdio(false);cin >> t;while (t--) {//初始化参数state = 1, Oi =  ans = spy = 0;memset(Ois, -1, sizeof(Ois));memset(alpha, 0, sizeof(alpha));cin >> n;cin >> buff;Oi = getfS(buff, 1);if (buff[2] == '1') Oi = 0;//输入for (int i = 1; i <= n; i++) { cin >> opt[i];if (opt[i] == 'F') {cin >> varN[i] >> sta[i] >> en[i];}}//n为奇数if (n % 2 == 1) state = 2;if (state == 2) { cout << "ERR" << endl; continue; }//遍历每层语句int h = 0;//当前复杂度int enter = 0; //判断当前循环能不能进入 int level = 0; //enter=1时spyfor (int i = 1; i <= n; i++) {int alphanum = getfS(varN[i], 2); //变量//F则循环+1if (opt[i] == 'F') {string a = sta[i], b = en[i];spy++; //判断变量有没有出现过if (alpha[alphanum]) {state = 2; break; }//如果没有出现过,则标记optt[spy] = alphanum;alpha[alphanum] = true;// sta为数字 end为n 复杂度为n Oi++if (a != "n" && b == "n" && enter == 0) h++, Ois[spy] = 1;else if ((a == "n" && b != "n" || getfS(a, 0) > getfS(b, 0)) && enter == 0) level = spy, enter = 1;}//E的时候判断是不是多E了即 E和F不匹配else {ans = max(ans, h);alpha[optt[spy]] = false;//销毁变量if (Ois[spy] == 1) h--, Ois[spy] = 0;spy--;if (level > 0 && spy < level) enter = level = 0;if (spy < 0) {state = 2; break;}}}if (state == 2 || spy != 0) { cout << "ERR" << endl; continue; }else {cout << (ans == Oi ? "Yes" : "No") << endl;}}return 0;
}

[NOIP2017 提高组] 时间复杂度相关推荐

  1. NOIP2017提高组比赛总结

    NOIP2017提高组比赛总结 前言 转眼间,NOIP2017(经常叫他NOIP,其实全称是全国青少年信息学奥林匹克联赛)就这么过去了.回望这2个月,既有参加NOIP的激动,也有赛场上一些失利的遗憾. ...

  2. 【NOIP2017提高组】列队

    题目背景 NOIP2017提高组 DAY2 T3 题目描述 Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵.Sylvia 所在的方阵中 ...

  3. [NOIp2017提高组]奶酪(BFS)

    [NOIp2017提高组_Day2T1]奶酪 1 #include<iostream> 2 #include<stdio.h> 3 #include<vector> ...

  4. P3959 [NOIP2017 提高组] 宝藏

    P3959 [NOIP2017 提高组] 宝藏 题意: 额题意不好说,就是n个点m个边,选定一个点为根节点,构造一个最小生成树,边的权值为该该边起点到根节点之间的点的数量K(不含根节点) * 道路长度 ...

  5. NOIP2017提高组模拟赛4 (总结)

    NOIP2017提高组模拟赛4 (总结) 第一题 约数 设K是一个正整数,设X是K的约数,且X不等于1也不等于K. 加了X后,K的值就变大了,你可以重复上面的步骤.例如K= 4,我们可以用上面的规则产 ...

  6. P3951 [NOIP2017 提高组] 小凯的疑惑 / [蓝桥杯 2013 省] 买不到的数目

    [NOIP2017 提高组] 小凯的疑惑 / [蓝桥杯 2013 省] 买不到的数目 题目背景 NOIP2017 提高组 D1T1 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每 ...

  7. 【NOIP2017提高组】小凯的疑惑

    小凯的疑惑 题目背景 NOIP2017提高组 DAY1 T1 题目描述 小凯手中有两种面值的金币,两种面值均为正整数且彼此互素.每种金币小凯都有无数个.在不找零的情况下,仅凭这两种金币,有些物品他是无 ...

  8. 【NOIP2017提高组】奶酪

    奶酪 题目背景 NOIP2017提高组 DAY2 T1 题目描述 现有一块大奶酪,它的高度为h,它的长度和宽度我们可以认为是无限大的,奶酪中间有许多半径相同的球形空洞.我们可以在这块奶酪中建立空间坐标 ...

  9. 洛谷 P3953 [NOIP2017 提高组] 逛公园

    开始刷题单啦~,这部分的洛谷好题作为个人训练记录和以后复习用,有兴趣的可以一起做做 题目链接:P3953 [NOIP2017 提高组] 逛公园 题意都是中文就不翻译了 题解:这是一道记忆化+搜索的题目 ...

最新文章

  1. “河边一群鹅,嘘声赶落河。捉得鹅来填肚饿,吃完回家玩老婆!”
  2. JDK+SDK 环境变量记录
  3. 国家邮政局公布一项数据 春节期间快递数量依旧很猛!
  4. 2008年8月30日人力资源系统启动会
  5. 计算机无法安装VC2015,我电脑安装C++2015和2017安装失败怎么解决?
  6. SWOT分析思维的一些基本思考与见解
  7. 【Python】:修改图片后缀
  8. 连接HDMI出现没声音
  9. 线性代数计算器C语言(1)——计算行列式值
  10. 医疗管理系统-检查项管理
  11. 网络安全ctf比赛/学习资源整理,解题工具、比赛时间、解题思路、实战靶场、学习路线,推荐收藏!...
  12. [错误解决] paramiko.ssh_exception.SSHException: Error reading SSH protocol banner
  13. PCIe TLP详解
  14. 正确的-配置Tomcat环境变量
  15. Docker 介绍、安装、基础搭建 --01
  16. 游记:分享阳光!(初次测试)
  17. 中小型网络系统总体规划与设计方法(一)
  18. 软件测试题目某市电话,软件测试题
  19. 适用于XP的AMD双核优化补丁集
  20. 工业相机分辨率怎么选择

热门文章

  1. JavaScript高级教程-代理与反射
  2. Java教程:Jasper-pdf打印类
  3. Java版的双色球买彩票程序
  4. 仿最新BiliBili客户端开源带后台弹幕库版
  5. 安装ubuntu或deepin报:failed to load ldlinux.c32的问题及解决步骤
  6. Ubuntu 16.04添加新硬盘操作流程
  7. Hadoop 安装(详细步骤)
  8. 程序员如何给孩子取名字?
  9. 不需要支撑结构的3D打印技术:多轴机器人3D打印系统
  10. 博客园android,博客园android客户端