【题目描述】

小明正在学习一种新的编程语言 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. 电脑查询pico的mac

    配置好adb或者sdk后,  adb shell cat /sys/class/net/wlan0/address

  2. 《机器学习技法》---soft-margin SVM

    1. soft-margin SVM的形式 其中ξn表示每个点允许的犯错程度(偏离margin有多远),但是犯错是有代价的,也就是目标函数里面要最小化的.c控制对犯错的容忍程度. 2. 推导soft ...

  3. vue 使用gojs绘制简单的流程图

    在vue项目中需要展示工作流进度,可以使用的流程图插件很多 flowchart.js  http://adrai.github.io/flowchart.js/ , 基于SVG创建Flow Chart ...

  4. 蔡勒(Zeller)公式及其推导:快速将任意日期转换为星期数

    0. 本文的初衷及蔡勒公式的用处 前一段时间,我在准备北邮计算机考研复试的时候,做了几道与日期计算相关的题目,在这个过程中我接触到了蔡勒公式.先简单的介绍一下蔡勒公式是干什么用的. 我们有时候会遇到这 ...

  5. C#_HttpWebRequest保存cookies模拟登录的方法

    CookieContainer cookies = new CookieContainer(); string url = "http://www.google.com.hk/"; ...

  6. (四十八)c#Winform自定义控件-下拉按钮

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  7. egret之每日登陆奖励

    //*******首登奖励********* */ //*********************** */ public setUserSetting(key, value) { if (value ...

  8. Delphi - cxGrid颜色显示相关设置

    1:单元格的值满足某个条件时,该单元格所在整行颜色设置整行字体设置 选中cxGridDBTableView,单击F11调出属性配置面板,在Events中双击OnCustomDrawCell后双击编辑重 ...

  9. 在Azure云上实现postgres主备切换

    以下是工作上实现postgres主备切换功能所用到的代码和步骤,中间走了不少弯路,在此记录下.所用到的操作系统为centos 7.5,安装了两台服务器,hostname为VM7的为Master,VM8 ...

  10. NLP(一)语料库和WordNet

    访问语料库 NLTK数据库的安装:http://www.nltk.org/data.html NLTK语料库列表:http://www.nltk.org/nltk_data/ 内部访问(以Reuter ...