【题目描述】

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

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

F i x y
循环体
E

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

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

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

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

【输入格式】

输入文件第一行一个正整数 t,表示有 t(t≤10)个程序需要计算时间复杂度。 每个程序我们只需抽取其中 F i x yE即可计算时间复杂度。注意:循环结构 允许嵌套。

接下来每个程序的第一行包含一个正整数 L 和一个字符串,L 代表程序行数,字符 串表示这个程序的复杂度,O(1)表示常数复杂度,O(n^w)表示复杂度为n^w,其 中w是一个小于100的正整数(输入中不包含引号),输入保证复杂度只有O(1)O(n^w) 两种类型。

接下来 LL 行代表程序中循环结构中的F i x y或者 E。 程序行若以F开头,表示进入一个循环,之后有空格分离的三个字符(串)i x y, 其中 ii 是一个小写字母(保证不为n),表示新建的变量名,x 和 y 可能是正整数或 n ,已知若为正整数则一定小于 100。

程序行若以E开头,则表示循环体结束。

【输出格式】

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

注意:即使在程序不会执行的循环体中出现了语法错误也会编译错误,要输出 ERR

【输入输出样例】

输入

 O()
F i
E
O(n^)
F x n
E
O()
F x n
O(n^)
F x n
F y n
E
E
O(n^)
F x n
E
F y n
E
O(n^)
F x n
F y n
E
E
O()
F y n
F x n
E
E
O(n^)
F x n
F x
E
E

输出

Yes
Yes
ERR
Yes
No
Yes
Yes
ERR

这题花了我近三个小时,本地AC评测就会RE两个点,心累……

这题当然是模拟,但是要考虑的东西很多,所以这题是一道蓝题。

1.首先考虑一下为什么会ERR:

1)有F而没有E

2)有E而没有F

3)变量用过了

看见前两个条件就非常自如的联想到了栈。

bool ok=true;
int word[]; if(word[i-'a'+]!=) word[i-'a'+]=;
else ok=false; if(p<) ok=false;//p是指针 if(ok==false) {printf("ERR\n");continue;}

2.再考虑一下计算复杂度

1)前为n且后为n -> 复杂度常数级别

2)前为n且后不为n -> 复杂度常数级别

3)前不为n且后为n -> 复杂度n级别

4)前不为n且后不为n -> 复杂度常数级别

5)如果在这条循环之前有一条循环不执行(前不为n且后为n或者说两个常数前面的比后面的大)-> 复杂度常数级别

for(int j=;j<len;j++)
{
if(s[j]>e[j]&&s[j]>=''&&s[j]<=''&&e[j]>=''&&e[j]<='')
{wyq=true;break;}
if(s[j]<e[j]&&s[j]>=''&&s[j]<=''&&e[j]>=''&&e[j]<='') break;
}//若都是常数,进行比较
if(strlen(s)>strlen(e)&&s[]>=''&&s[]<=''&&e[]>=''&&e[]<='') h[p+].lxp=true;
if(wyq||(s[]=='n'&&e[]!='n')) h[p+].lxp=true;//判断代码是否有运行

for(int k=;k<=p+;k++)
if(h[k].lxp==true)
{h[++p].data='';h[p].old=i;wyc=true;break;}//前面的比后面的大,当作是常数级别
if(wyc) continue;
if(s[]=='n'&&e[]=='n') {h[++p].data='';h[p].old=i;}
if(s[]=='n'&&e[]!='n') {h[++p].data='';h[p].old=i;}
if(s[]!='n'&&e[]=='n') {h[++p].data='n';h[p].old=i;}
if(s[]!='n'&&e[]!='n') {h[++p].data='';h[p].old=i;}

3.再然后就是最后的判断和最开始的初始化

感觉没什么问题可还是RE了

上代码

#include<bits/stdc++.h>
using namespace std;
int t,p=;
struct node{
char data;
char old;
int maxn;//用来储存栈中第i层最大的时间复杂度
bool lxp;//判断代码是否有运行
}h[];//栈,看是否匹配
int l,word[];//word是看这个变量用过没有
char o[];
int num=,sum=;
int main()
{
// freopen("hh1.in","r",stdin);
// freopen("hh1.out","w",stdout);
scanf("%d",&t);
while(t--)
{
for(int k=;k<=;k++) {h[k].maxn=;h[k].data=;h[k].old=;h[k].lxp=false;}
for(int i=;i<=;i++) word[i]=;
sum=;p=;num=;//每条程序重置一次
scanf("%d%s",&l,o);
bool flag=false;//判断是常数还是n^w
bool ok=true;
if(strlen(o)==) flag=true;
else
{
int n=strlen(o);
for(int i=;i<n;i++)
if(o[i]<=''&&o[i]>='')
num=num*+o[i]-'';
}
while(l--)
{
char c,i,s[],e[];
cin>>c;
if(c=='F')
{
sum=;//将指数重置
cin>>i>>s>>e;
bool wyq=false,wyc=false;//临时变量,不用管意义
int len=strlen(s);
for(int j=;j<len;j++)
{
if(s[j]>e[j]&&s[j]>=''&&s[j]<=''&&e[j]>=''&&e[j]<='')
{wyq=true;break;}
if(s[j]<e[j]&&s[j]>=''&&s[j]<=''&&e[j]>=''&&e[j]<='') break;
}//若都是常数,进行比较
if(strlen(s)>strlen(e)&&s[]>=''&&s[]<=''&&e[]>=''&&e[]<='') h[p+].lxp=true;
if(wyq||(s[]=='n'&&e[]!='n')) h[p+].lxp=true;//判断代码是否有运行
if(word[i-'a'+]!=) word[i-'a'+]=;
else ok=false;
for(int k=;k<=p+;k++)
if(h[k].lxp==true)
{h[++p].data='';h[p].old=i;wyc=true;break;}//前面的比后面的大,当作是常数级别
if(wyc) continue;
if(s[]=='n'&&e[]=='n') {h[++p].data='';h[p].old=i;}
if(s[]=='n'&&e[]!='n') {h[++p].data='';h[p].old=i;}
if(s[]!='n'&&e[]=='n') {h[++p].data='n';h[p].old=i;}
if(s[]!='n'&&e[]!='n') {h[++p].data='';h[p].old=i;}
}
if(c=='E')
{
if(h[p].data==) p--;
if(h[p].data=='n') sum=h[p+].maxn+;//前一层为n^1级别的就指数+1
else sum=h[p+].maxn*;
h[p].maxn=max(sum,h[p].maxn);//存储到这时最大的指数
h[p+].maxn=;
word[h[p].old-'a'+]=;
h[p].lxp=false;
p--;
if(p<) ok=false;
}
}
if(ok==false) {printf("ERR\n");continue;}//如果变量用过了或括号不匹配,错误,跳出去
if(p>) {printf("ERR\n");continue;}
if(flag&&h[].maxn==) printf("Yes\n");
else if(!flag&&h[].maxn-==num) printf("Yes\n");
else printf("No\n");
}
return ;
}

洛谷 P3952时间复杂度 (本地AC测评RE的伪题解)的更多相关文章

  1. 洛谷 P3952 时间复杂度 解题报告

    P3952 时间复杂度 题目描述 小明正在学习一种新的编程语言A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会 ...

  2. 洛谷P3952 时间复杂度【字符串】【模拟】

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

  3. 洛谷P3952 时间复杂度

    大毒瘤...... 时隔快半年我终于花了两个小时堪堪A掉这一题...果然我还没有准备好. 想法:用DFS模拟递归. 时间复杂度的处理:每层循环取max,然后相加. 最大难点:各种繁杂而令人发指的特判. ...

  4. 洛谷 - P3952 - 时间复杂度 - 模拟

    https://www.luogu.org/problemnew/show/P3952 这个模拟,注意每次进入循环的时候把新状态全部入栈,退出循环的时候就退栈. 第一次就错在发现ERR退出太及时,把剩 ...

  5. 计蒜客 时间复杂度 (模拟) & 洛谷 P3952 时间复杂度

    链接 : Here! 思路 : 这是一道大模拟, 区分好情况就没问题了 循环构成部分 : $F , x , i , j$ 和 $E$ , 需要注意的是 $i , j$, - 分析 $i, j$ 的情况 ...

  6. 2018.11.02 洛谷P3952 时间复杂度(模拟)

    传送门 惊叹考场dubuffdubuffdubuff. 这题还没有梭哈难啊233. 直接按照题意模拟就行了. 代码: #include<bits/stdc++.h> using names ...

  7. 洛谷P3952 时间复杂度(模拟)

    题意 题目链接 Sol 咕了一年的题解..就是个模拟吧 考场上写的递归也是醉了... 感觉一年自己进步了不少啊..面向数据编程的能力提高了不少 #include<bits/stdc++.h> ...

  8. 洛谷 P3952 时间复杂度【模拟】

    把No写成NO,WA了一发-- 现在看这题也不难-- 用一个栈,记一下前面F的字母,是否合法,合法的有多长,每次入栈弹栈即可 #include<iostream> #include< ...

  9. 【题解】洛谷P3952 [NOIP2017TG] 时间复杂度(模拟)

    题目来源:洛谷P3952 思路 纯模拟没啥可说的了 果然好复杂 参考了你谷一个40行代码 代码 #include<iostream> #include<cstdio> #inc ...

随机推荐

  1. Netty学习(九)-Netty编解码技术之Marshalling

    前面我们讲过protobuf的使用,主流的编解码框架其实还有很多种: ①JBoss的Marshalling包 ②google的Protobuf ③基于Protobuf的Kyro ④Apache的Thr ...

  2. alluxio源码解析-rpc调用概述-client和worker之间的block模块的通讯架构(netty版本)(3)

    (1.8版本)client和worker之间的block模块的通讯架构 block作为alluxio文件读取或者存储的最小基本单位,都是通过BlockOutStream和BlockInputtream ...

  3. android ——滑动菜单

    一.DrawerLayout是一个拥有两个子控件的布局,第一个子控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容: <android.support.v4.widget.Drawer ...

  4. java线程池,阿里为什么不允许使用Executors?

    带着问题 阿里Java代码规范为什么不允许使用Executors快速创建线程池? 下面的代码输出是什么? ThreadPoolExecutor executor = new ThreadPoolExe ...

  5. imageloader+图片压缩

    public class MainActivity extends AppCompatActivity { private ImageView ivIcon; @Override protected ...

  6. JQGrid之文件上传

    文件/图片上传功能,简单总结如下 1.引入ajaxfileupload.js 注意:该文件需要在引入Jquery之后引入 下载链接:https://i.cnblogs.com/Files.aspx 2 ...

  7. 重学计算机组成原理(十一)- 门电路的"千里传音"

    人用纸和笔来做运算,都是用十进制,直接用十进制和我们最熟悉的符号不是最简单么? 为什么计算机里我们最终要选择二进制呢? 来看看,计算机在硬件层面究竟是怎么表示二进制的,你就会明白,为什么计算机会选择二 ...

  8. 从零开始一起学习SLAM | 用四元数插值来对齐IMU和图像帧

    视觉 Vs. IMU 小白:师兄,好久没见到你了啊,我最近在看IMU(Inertial Measurement Unit,惯性导航单元)相关的东西,正好有问题求助啊 师兄:又遇到啥问题啦? 小白:是这 ...

  9. Springboot源码分析之番外篇

    摘要: 大家都知道注解是实现了java.lang.annotation.Annotation接口,眼见为实,耳听为虚,有时候眼见也不一定是真实的. /** * The common interface ...

  10. idea打开eclipse项目并部署至tomcat

    前言:因为遇到了用idea打开eclipse项目并配置外置tomact的场景,经过实验也成功了,所以特地来记录一下. 导入eclipse项目 这里我们导入的eclipse下开发的maven项目,直接点 ...