洛谷 P3952时间复杂度 (本地AC测评RE的伪题解)
【题目描述】
小明正在学习一种新的编程语言 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的伪题解)的更多相关文章
- 洛谷 P3952 时间复杂度 解题报告
P3952 时间复杂度 题目描述 小明正在学习一种新的编程语言A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会 ...
- 洛谷P3952 时间复杂度【字符串】【模拟】
题目描述 小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序 ...
- 洛谷P3952 时间复杂度
大毒瘤...... 时隔快半年我终于花了两个小时堪堪A掉这一题...果然我还没有准备好. 想法:用DFS模拟递归. 时间复杂度的处理:每层循环取max,然后相加. 最大难点:各种繁杂而令人发指的特判. ...
- 洛谷 - P3952 - 时间复杂度 - 模拟
https://www.luogu.org/problemnew/show/P3952 这个模拟,注意每次进入循环的时候把新状态全部入栈,退出循环的时候就退栈. 第一次就错在发现ERR退出太及时,把剩 ...
- 计蒜客 时间复杂度 (模拟) & 洛谷 P3952 时间复杂度
链接 : Here! 思路 : 这是一道大模拟, 区分好情况就没问题了 循环构成部分 : $F , x , i , j$ 和 $E$ , 需要注意的是 $i , j$, - 分析 $i, j$ 的情况 ...
- 2018.11.02 洛谷P3952 时间复杂度(模拟)
传送门 惊叹考场dubuffdubuffdubuff. 这题还没有梭哈难啊233. 直接按照题意模拟就行了. 代码: #include<bits/stdc++.h> using names ...
- 洛谷P3952 时间复杂度(模拟)
题意 题目链接 Sol 咕了一年的题解..就是个模拟吧 考场上写的递归也是醉了... 感觉一年自己进步了不少啊..面向数据编程的能力提高了不少 #include<bits/stdc++.h> ...
- 洛谷 P3952 时间复杂度【模拟】
把No写成NO,WA了一发-- 现在看这题也不难-- 用一个栈,记一下前面F的字母,是否合法,合法的有多长,每次入栈弹栈即可 #include<iostream> #include< ...
- 【题解】洛谷P3952 [NOIP2017TG] 时间复杂度(模拟)
题目来源:洛谷P3952 思路 纯模拟没啥可说的了 果然好复杂 参考了你谷一个40行代码 代码 #include<iostream> #include<cstdio> #inc ...
随机推荐
- Appium+python自动化(三十)- 实现代码与数据分离 - 数据配置-yaml(超详解)
简介 本篇文章主要介绍了python中yaml配置文件模块的使用让其完成数据和代码的分离,宏哥觉得挺不错的,于是就义无反顾地分享给大家,也给大家做个参考.一起跟随宏哥过来看看吧. 思考问题 前面我们配 ...
- Java内存映射,上G大文件轻松处理
内存映射文件(Memory-mapped File),指的是将一段虚拟内存逐字节映射于一个文件,使得应用程序处理文件如同访问主内存(但在真正使用到这些数据前却不会消耗物理内存,也不会有读写磁盘的操作) ...
- Springboot 优雅停止服务的几种方法
在使用Springboot的时候,都要涉及到服务的停止和启动,当我们停止服务的时候,很多时候大家都是kill -9 直接把程序进程杀掉,这样程序不会执行优雅的关闭.而且一些没有执行完的程序就会直接退出 ...
- Oracle中的转换函数
Oracle中的转换函数有三个,分别为to_char(),to_date(),to_number() 1.to_char()的用法 格式化当前的日期时间 select sysdate,to_char( ...
- 11.源码分析---SOFARPC数据透传是实现的?
先把栗子放上,让大家方便测试用: Service端 public static void main(String[] args) { ServerConfig serverConfig = new S ...
- malloc和free
1.系统使用红黑树管理空闲堆空间,malloc是申请了堆一块内存的使用权,拿到了这个钥匙,然后红黑树该块的空闲标记被去除. 2.free后,红黑树重新标记该块内存为空闲,其他程序就可以申请到此块内存. ...
- 浅析runtime包中的三个方法Gosched、Goexit、GOMAXPROCS
Gosched 暂停当前goroutine,使其他goroutine先行运算.只是暂停,不是挂起,当时间片轮转到该协程时,Gosched()后面的操作将自动恢复 未使用Gosched的代码 packa ...
- springboot报 org.thymeleaf.exceptions.TemplateInputException: Error resolving template "succeed";
--------------------- 本文转自 林晓风 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/Lin_xiaofeng/article/details/ ...
- 做「容量预估」可没有true和false
如果第二次看到我的文章,欢迎右侧扫码订阅我哟~
- 操作系统-IO管理概述
IO管理概述 一.IO设备 IO设备管理是操作系统设计中最凌乱也最具挑战性的部分.由于它包含了很多领域的不同设备以及与设备相关的应用程序,因此很难有一个通用且一直的设计方案.所以在理解设备管理之前,应 ...