有的题做了很久\感想比较深\可以引申很多\上台讲过,所以单开一篇,不放在总结下面。

  这道题做的时候花了很长时间,犯的错也比较典型,当时写过一篇单独的总结,放在学校了,返校后粘上来。

  

时间复杂度

  小明正在学习一种新的编程语言 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) 两种类型。

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

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


  模拟题。

  多组数据,要记得清空数组。

  首先读入行数以及std的时间复杂度。

  第一次做的时候发现std的复杂度可能不是一位数,然而还是处理错了,最坑的是对于小数据的处理是完全没有问题的,只有在数据达到一定程度时才能看出来,所以以后编程时写好一部分就要先测试,比如说这道题的std,编写完就应该测试各种情况如O(1),O(n^1),O(n^99)之类的情况,而不是等全写完了之后再改,很容易出错。一开始写的两位数处理中十位和个位是反的。。。。。。

  正确的代码如下:

  接着读入程序的每一行,先判断是否有语法错误,这一块感觉很难,其实却是最简单的部分。

  1. 变量冲突:维护一个栈,存放目前每一层的循环变量,当循环结束时将本层的循环变量销毁。如果某个变量当前正在被使用,又有新的变量要用同样的变量名,这个程序就出现了语法错误。
  2. 开始与结束不匹配:每读到一个F开头的句子,栈的深度+1,读到E开头的句子,深度-1。如果深度在某一次被减到<0了,证明语法错误,如果程序结束了深度却不为0,也是错的。

  最后再计算时间复杂度。

  这一块是最复杂的,每一层的时间复杂度等于本层的复杂度加上下一层中复杂度最大的一个,在dep层结束时再更新dep+1层的复杂度,否则会出错,注意,如果本层根本就不执行,它的时间复杂度一定是0,而不能再加上下一层的复杂度。这一部分其实一开始也想到了,但是改着改着就给忘了,以后做这种大模拟如果想到什么细节就写在纸上,到最后提交前再检查一下,因为边写边改的话过一会就忘了这一句有什么用,可能不小心就删了。

  现在就只剩下计算本层的时间复杂度了。

  除去循环变量和F,开始和结束共有9种情况:

  

F

i

n

n

F

i

n

1

F

i

n

1

2

F

i

1

n

F

i

1

1

F

i

1

1

2

F

i

1

2

n

F

i

1

2

1

F

i

1

2

1

2

  如果是n,就用-1表示。

    

如果be和en相等,常数复杂度;

如果be是n,en是常数,不执行;

如果en是常数,be是n,n的复杂度;

如果en和be都是常数:be<=en,常数复杂度;

如果be>en,不执行。

# include <cstdio>
# include <iostream>
# include <cstring>
# include <cstring> using namespace std; int t,len,nl,Std,dep;
string st,pr[];
bool uke,f,vis[]={};
int sta[],maxa[];
int ans[],F[]; void ac()
{
for (int i=;i<=len;i++)
{
if(pr[i][]=='F')
{
dep++;
sta[dep]=pr[i][]-'a';
if (vis[sta[dep]]) uke=true;
vis[sta[dep]]=true;
}
else
{
if(dep==) uke=true;
vis[sta[dep]]=false;
dep--;
}
}
if(dep!=) uke=true;
return ;
} bool wa()
{
memset(maxa,,sizeof(maxa));
string no;
int be,en;
for (int i=;i<=len;i++)
{
if(pr[i][]=='F')
{
dep++;
no=pr[i];
int ss=;
if(no[]=='n')
{
be=-;
if(no[]=='n') en=-;
else if(no[]>=''&&no[]<='') en=(no[]-'')*+no[]-'';
else en=no[]-'';
}
else if(no[]==' ')
{
be=no[]-'';
if(no[]=='n') en=-;
else if(no[]>=''&&no[]<='') en=(no[]-'')*+no[]-'';
else en=no[]-'';
}
else
{
be=(no[]-'')*+no[]-'';
if(no[]=='n') en=-;
else if(no[]>=''&&no[]<='') en=(no[]-'')*+no[]-'';
else en=no[]-'';
}
if(be==en)
ss=;
else if(be==-)
ss=-;
else if(en==-)
ss=;
else if(be<=en)
ss=;
else
ss=-;
ans[dep]=ss;
}
else
{
if(ans[dep]!=-) ans[dep]+=maxa[dep];
maxa[dep-]=max(maxa[dep-],ans[dep]);
ans[dep]=;
maxa[dep]=;
dep--;
}
}
if(maxa[]==Std) return true;
return false;
} int main()
{
scanf("%d",&t);
for (int shzr=;shzr<=t;shzr++)
{
scanf("%d",&len);
getline(cin,st);
if(st[]=='') Std=;
else
{
if(st[]==')') Std=st[]-'';
else Std=(st[]-'')*+st[]-'';
}
memset(vis,,sizeof(vis));
memset(ans,,sizeof(ans));
memset(F,,sizeof(F));
uke=f=false;
for (int i=;i<=len;i++)
getline(cin,pr[i]);
dep=;
ac();
if(uke) printf("ERR\n");
else
{
dep=;
if(wa()) printf("Yes\n");
else printf("No\n");
}
}
return ;
}

时间复杂度

终于写完啦qwq。

---shzr

时间复杂度 NOIP_2017_D1T2的更多相关文章

  1. 时间复杂度分别为 O(n)和 O(1)的删除单链表结点的方法

    有一个单链表,提供了头指针和一个结点指针,设计一个函数,在 O(1)时间内删除该结点指针指向的结点. 众所周知,链表无法随机存储,只能从头到尾去遍历整个链表,遇到目标节点之后删除之,这是最常规的思路和 ...

  2. 斐波拉契数列加强版——时间复杂度O(1),空间复杂度O(1)

    对于斐波拉契经典问题,我们都非常熟悉,通过递推公式F(n) = F(n - ) + F(n - ),我们可以在线性时间内求出第n项F(n),现在考虑斐波拉契的加强版,我们要求的项数n的范围为int范围 ...

  3. C语言数组实现约瑟夫环问题,以及对其进行时间复杂度分析

    尝试表达 本人试着去表达约瑟夫环问题:一群人围成一个圈,作这样的一个游戏,选定一个人作起点以及数数的方向,这个人先数1,到下一个人数2,直到数到游戏规则约定那个数的人,比如是3,数到3的那个人就离开这 ...

  4. 实现一个 能在O(1)时间复杂度 完成 Push、Pop、Min操作的 栈

    一,问题描述 实现一个栈(元素遵守先入后出顺序),能够通过 min 方法在 O(1)时间内获取栈中的最小元素.同时,栈的基本操作:入栈(Push).出栈(Pop),也是在O(1)时间内完成的. 二,问 ...

  5. 设计一个Stack,要求Push、Pop、获取最大最小值时间复杂度都为O(1)

    面试的时候,面试官让设计一个栈,要求有Push.Pop和获取最大最小值的操作,并且所有的操作都能够在O(1)的时间复杂度完成. 当时真没啥思路,后来在网上查了一下,恍然大悟,只能恨自己见识短浅.思路不 ...

  6. Linux内核完全注释阅读笔记1:O(1)时间复杂度查找timeout定时器

    前言 一直有Linux kernel情节,之前也一直在看Linux kernel相关的书和代码,但是每次到最后又由于兴趣转变而荒废了.这次终于静下心来想把Linux内核相关的代码好好看看,算是对自己的 ...

  7. 数据结构(C语言第2版)----时间复杂度和单链表

    马上要到校招了,复习下相关的基础知识. 时间复杂度是什么? 官方解释: 算法的执行时间需要依据算法所编制的程序在计算机上于运行时所消耗的时间来度量.在算法中可以使用基本的语句的执行次数作为算法的时间复 ...

  8. 时间复杂度---我又要想起初中数学老师的脸了xxxxx

    时间复杂度: 常用的时间复杂度有:常数级,对数级,线性级 线性对数级 平方级,立方级别,多项式级别,指数级别,阶乘级别 这里我们主要探讨对数级,线性级,平方级,指数级---为什么不讨论其他的?别的我也 ...

  9. 【编程题目】如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1)

    转自:http://blog.csdn.net/vast_sea/article/details/8167968 看上去似乎任何已知的算法都无法做到,如果谁做到了,那么所有的排序方法:QuickSor ...

随机推荐

  1. 转载:SQL按照日、周、月、年统计数据的方法

    转载源:http://www.jb51.net/article/42613.htm SQL按照日.周.月.季度.年统计数据的方法 方式一: --按日 select sum(consume),day([ ...

  2. Navbar和Tabbar常用设置

    1.navBar [self.navigationController.navigationBar setBackgroundImage:navBarImage forBarMetrics:UIBar ...

  3. (mysql)找不到请求的 .Net Framework Data Provider。可能没有安装

    webconfig配置以下节点(注意版本号) <system.data> <DbProviderFactories> <add name="MySQL Data ...

  4. POJ1321(KB1-A 简单搜索)

    棋盘问题 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 40872 Accepted: 19936 Description 在一 ...

  5. 不使用JavaScript让IE浏览器支持HTML5元素——张鑫旭

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=2515 如果我们不做什 ...

  6. java-单例详解

    java单例模式(Singleton)以及实现 一. 什么是单例模式 因程序需要,有时我们只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计. 二. 单例模式的特点 1. ...

  7. JavaScript document和window属性及方法详解

    [document对象] 该对象是window和frames对象的一个属性,是显示于窗口或框架内的一个文档. 属性 alinkColor 活动链接的颜色(ALINK)  anchor 一个HTMI锚点 ...

  8. 网络基础 Windows下安装和配置net-snmp 代理

    Windows 下安装和配置net-snmp 代理[摘录] by:授客 QQ:1033553122   A.   安装  1.   安装前准备 ActivePerl-5.10.0.1004-MSWin ...

  9. Pig order by用法举例

    sorted = order data by $0;   数值类型按照数值大小比较 chararray类型按照字符的字典顺序比较 bytearray按照字节的字典顺序比较 复杂类型(map.tuple ...

  10. -webkit-min-device-pixel-ratio: 2是什么意思?

    DPI(DPR) stands for Dots Per Inch which technically means printer dots per inch. 这个参数实际上量化了屏幕的物理分辨率和 ...