P3952 时间复杂度
题目描述
小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正确。
A++语言的循环结构如下:
F i x y
循环体
E其中
F i x y表示新建变量 ii(变量 ii 不可与未被销毁的变量重名)并初始化为 xx, 然后判断 ii和 yy 的大小关系,若 ii 小于等于 yy 则进入循环,否则不进入。每次循环结束后 ii 都会被修改成 i +1i+1,一旦 ii 大于 yy 终止循环。xx 和 yy 可以是正整数(xx 和 yy 的大小关系不定)或变量 nn。nn 是一个表示数据规模的变量,在时间复杂度计算中需保留该变量而不能将其视为常数,该数远大于 100100。
“E”表示循环体结束。循环体结束时,这个循环体新建的变量也被销毁。
注:本题中为了书写方便,在描述复杂度时,使用大写英文字母“O”表示通常意义下“Θ”的概念。
输入输出格式
输入格式:
输入文件第一行一个正整数 t,表示有 t(t<=10)个程序需要计算时间复杂度。 每个程序我们只需抽取其中
F i x y和E即可计算时间复杂度。注意:循环结构 允许嵌套。接下来每个程序的第一行包含一个正整数 LL 和一个字符串,LL 代表程序行数,字符 串表示这个程序的复杂度,
O(1)表示常数复杂度,O(n^w)表示复杂度为n^w,其 中w是一个小于100的正整数(输入中不包含引号),输入保证复杂度只有O(1)和O(n^w)两种类型。接下来 L 行代表程序中循环结构中的
F i x y或者E。 程序行若以F开头,表示进入一个循环,之后有空格分离的三个字符(串)i x y, 其中 ii 是一个小写字母(保证不为n),表示新建的变量名,x 和 y 可能是正整数或 nn ,已知若为正整数则一定小于 100。程序行若以
E开头,则表示循环体结束。输出格式:
输出文件共 t行,对应输入的 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】
第一个程序 i从 1 到 1 是常数复杂度。
第二个程序 x 从 1 到 n 是 n 的一次方的复杂度。
第三个程序有一个
F开启循环却没有E结束,语法错误。第四个程序二重循环,n 的平方的复杂度。
第五个程序两个一重循环,n 的一次方的复杂度。
第六个程序第一重循环正常,但第二重循环开始即终止(因为n远大于100,100大于4)。
第七个程序第一重循环无法进入,故为常数复杂度。
第八个程序第二重循环中的变量 x 与第一重循环中的变量重复,出现语法错误②,输出
ERR。【数据规模与约定】
对于 %30%的数据:不存在语法错误,数据保证小明给出的每个程序的前 L/2 行一定为以
F开头的语句,第 L/2+1 行至第 L 行一定为以 E开头的语句,L≤10,若 x、y 均 为整数,x 一定小于 y,且只有 yy 有可能为 nn。对于 50%的数据:不存在语法错误,L <=100,且若 x、y 均为整数,x 一定小于 y, 且只有 y有可能为 n。
对于 70%的数据:不存在语法错误,L≤100。
对于 100%的数据:L≤100。
思路:
直接用getline(cin,str)一行一行读,写一个get_num获取其中的数字,将'n'视为一个极大的数
- 用一个栈模拟存变量,ins标记是否被定义过,用来判ERR,used表示该变量对复杂度是否有贡献,用flag来维护最早的不能进入循环的变量(如for int i=3 ; i<=1 ; i++),因为在它之后的根本不能运行,初始化为-1,出栈时判一下如果flag=k,则其后面的语句又可以正常运行了,令flag=-1.
代码
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cctype>
#include <cmath>
#include <stack>
using namespace std; #define res register int
int T,n;
stack <int> s;
bool ins[],used[];//是否在栈中,对时间复杂度是否有贡献
string o,code[]; template <typename T>
inline T my_max(T a,T b) {return a>b?a:b;}
template <typename T>
inline T my_min(T a,T b) {return a<b?a:b;} inline int get_num(int &x,string c)
{
int tmp(),len=c.size();
while(!isdigit(c[x]) && x<len)
{
if(c[x]=='n') {++x; return ;}
++x;
}
while(isdigit(c[x])) {
tmp=tmp*+c[x]-'';
x++;
}
return tmp;
} inline int get_o()
{
int tmp(),x=;
if(o[]=='n') tmp=get_num(x,o);
else tmp=;//O(1)对应0
return tmp;
} inline int check()
{
int now(),cp();//complexity
int a,b,x;
while(s.size()) s.pop();
memset(ins,,sizeof(ins));
memset(used,,sizeof(used));
int flag(-);
for(res i= ; i<=n ; i++)
{
if(code[i][]=='F')
{
int k=code[i][]-'a';
if(ins[k]) return -;
ins[k]=true; s.push(k);
x=;
a=get_num(x,code[i]);
b=get_num(x,code[i]);
//flag为最早的不能循环的对应的变量k,可以正常循环时为-1
if(b-a> && flag==-)
{
used[k]=true; now++;
cp=my_max(cp,now);
}
else if(a>b && flag==-)
flag=k;
}
else
if(code[i][]=='E')
{
if(s.empty()) return -;
int k=s.top();
s.pop(); ins[k]=false;
if(flag==k) flag=-;
if(used[k]) now--,used[k]=false;
}
}
if(s.size()) return -;
return cp;
} int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d ",&n);
getline(cin,o);
int x0=get_o();
for(res i= ; i<=n ; i++)
getline(cin,code[i]);
int x1=check();
if(x1==-) puts("ERR");
else
{
if(x0==x1) puts("Yes");
else puts("No");
}
}
// system("pause");
return ;
}
P3952 时间复杂度的更多相关文章
- luogu P3952 时间复杂度 模拟
题目链接 luogu P3952 时间复杂度 题解 直接模拟即可 注意不要直接return 我真是naive ...... 代码 #include<map> #include<sta ...
- 洛谷 P3952 时间复杂度 解题报告
P3952 时间复杂度 题目描述 小明正在学习一种新的编程语言A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会 ...
- 洛谷P3952 时间复杂度【字符串】【模拟】
题目描述 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序 ...
- 【luogu P3952 时间复杂度】 题解
对于2017 D1 T2 这道题 实实在在是个码力题,非常考验耐心. 其实大体的思路并不是非常难想出来,但是要注意的小细节比较多. 题目链接:https://www.luogu.org/problem ...
- 洛谷 - P3952 - 时间复杂度 - 模拟
https://www.luogu.org/problemnew/show/P3952 这个模拟,注意每次进入循环的时候把新状态全部入栈,退出循环的时候就退栈. 第一次就错在发现ERR退出太及时,把剩 ...
- 洛谷P3952 时间复杂度
大毒瘤...... 时隔快半年我终于花了两个小时堪堪A掉这一题...果然我还没有准备好. 想法:用DFS模拟递归. 时间复杂度的处理:每层循环取max,然后相加. 最大难点:各种繁杂而令人发指的特判. ...
- LOJ P3952 时间复杂度 noip 暴力 模拟
https://www.luogu.org/problemnew/show/P3952 模拟,日常认识到自己zz. #include<iostream> #include<cstdi ...
- [LUOGU] P3952 时间复杂度
其实,也没那么难写 这种模拟题,仔细分析一下输入格式,分析可能的情况,把思路写在纸上,逐步求精,注意代码实现 主要思路就是算一个时间复杂度,和给出的复杂度比较,这就先设计一个函数把给出的复杂度由字符串 ...
- 计蒜客 时间复杂度 (模拟) & 洛谷 P3952 时间复杂度
链接 : Here! 思路 : 这是一道大模拟, 区分好情况就没问题了 循环构成部分 : $F , x , i , j$ 和 $E$ , 需要注意的是 $i , j$, - 分析 $i, j$ 的情况 ...
随机推荐
- 273. Integer to English Words数字转为单词
[抄题]: Convert a non-negative integer to its english words representation. Given input is guaranteed ...
- 657. Judge Route Circle机器人能否返回
[抄题]: Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this r ...
- redis 面试题1 有用
1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.Reids的特点 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库 ...
- ubuntu14.04 64 位 vmware tools 问题
当提示说open-vm-tools版本太低时可以这样解决 1.sudo apt-get autoremove open-vm-dkms open-vm-tools --purge 2.安装vmware ...
- Python手机开发调用DLL实现部分ADB功能-乾颐堂
近期学了一点Python,然后正好有一个手机同步工具方面的预研工作要完成. 要实现PC与手机的通信,首先要找到他们的通信协议,还好的是Android有完善的协议:ADB ADB的代码是开源的,而且支持 ...
- NHibernate获取实体配置信息(表名,列名等等)
// 注意这里有个&符号,并不是写错了,而是约定 就是这样写的ctx.GetObject("&SessionFactory") 这是官网地址http://nhfor ...
- 扩展JPA方法,重写save方法
为什么要重构save? jpa提供的save方法会将原有数据置为null,而大多数情况下我们只希望跟新自己传入的参数,所以便有了重写或者新增一个save方法. 本着解决这个问题,网上搜了很多解决方案, ...
- mongodb学习-创建唯一索引(在已存在的集合创建)
如果在已存在的集合创建,可能会存在相同的值如下: 我们可以使用(2.x版本) db.users.ensureIndex({uid:1, name:1}, {unique:true, dropDups: ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(8):装配SpringBean概述(如何合理使用装配级别)
一. 装配Bean概述 关于如何将自己开发的Bean配置到Spring IoC容器中,大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功 ...
- 设置emacs启动窗口的两种方法
1. 设置位置和大小 ;;设置窗口位置为屏库左上角(0,0) (set-frame-position (selected-frame) 0 0) ;;设置宽和高 (set-frame-width (s ...