【题目描述】

小明正在学习一种新的编程语言 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 y和E即可计算时间复杂度。注意:循环结构 允许嵌套。

接下来每个程序的第一行包含一个正整数 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 个程序,每行输出Yes或No或者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. ccf 201903-3 损坏的RAID5

    9月份考ccf,暑假打算做一些往年的真题... 这个题,一开始真是把我给看晕了 传说中的大模拟,果然不简单QAQ 首先读懂题目就是一个大难点,特别是对于我这种题目一长就看不进去的人来说 读懂题目之后, ...

  2. Redis集群与spring的整合

    上一篇详细的赘述了Redis的curd操作及集群的搭建.下面我们开始将他整合到我们实际的项目中去.我的项目采用的是标准的ssm框架,ssm框架这里不说,直接开始整合. 首先在maven管理中将我们的j ...

  3. poj 1286 polya定理

    Necklace of Beads Description Beads of red, blue or green colors are connected together into a circu ...

  4. Hive 系列(五)—— Hive 分区表和分桶表

    一.分区表 1.1 概念 Hive 中的表对应为 HDFS 上的指定目录,在查询数据时候,默认会对全表进行扫描,这样时间和性能的消耗都非常大. 分区为 HDFS 上表目录的子目录,数据按照分区存储在子 ...

  5. 那些必会用到的 ES6 精粹

    前言 最新的 ECMAScript 都已经到发布到 2019 版了. 我们应该有的态度是: Stay hungry ! Stay young ! 从接触 vue 到工作中用到 vue 将近 2 年了, ...

  6. Ribbon实现客户端负载均衡

    什么是Ribbon? 客户端负载均衡组件. 前期准备: 搭建一个Eureka集群和一个注册服务 https://www.cnblogs.com/noneplus/p/11374883.html 创建服 ...

  7. Http协议4个新的http状态码:428、429、431、511;

    1.428 Precondition Required (要求先决条件) 先决条件是客户端发送 HTTP 请求时,必须要满足的一些预设条件.一个好的例子就是 If-None-Match 头,经常用在 ...

  8. webrtc笔记(1): 基于coturn项目的stun/turn服务器搭建

    webrtc是google推出的基于浏览器的实时语音-视频通讯架构.其典型的应用场景为:浏览器之间端到端(p2p)实时视频对话,但由于网络环境的复杂性(比如:路由器/交换机/防火墙等),浏览器与浏览器 ...

  9. JS-对象的深浅拷贝及其新增方法测试

    我们在了解数据类型的时候,都知道一般的字符,数值,undefined和布尔值等都为一般数据类型,它们在进行数据传输的时候,进行的是值传递,当我们修改新数据,是不影响老数据的.但是我们今天要讲的是数据类 ...

  10. HTML连载34-背景关联和缩写以及插图图片和背景图片的区别

    一.背景属性缩写的格式 1.backgound:背景颜色  背景图片  平铺方式  关联方式  定位方式 2.注意点: 这里的所有值都可以省略,但是至少需要一个 3.什么是背景关联方式 默认情况下,背 ...