洛谷P3952 时间复杂度

题目:https://www.luogu.org/problemnew/show/3952

题目描述

小明正在学习一种新的编程语言 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, 其中 i 是一个小写字母(保证不为n),表示新建的变量名,x 和 y 可能是正整数或 n ,已知若为正整数则一定小于 100。

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

输出格式:

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

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

输入输出样例

输入样例#1:

8
2 O(1)
F i 1 1
E
2 O(n^1)
F x 1 n
E
1 O(1)
F x 1 n
4 O(n^2)
F x 5 n
F y 10 n
E
E
4 O(n^2)
F x 9 n
E
F y 2 n
E
4 O(n^1)
F x 9 n
F y n 4
E
E
4 O(1)
F y n 4
F x 9 n
E
E
4 O(n^2)
F x 1 n
F x 1 10
E
E

输出样例#1:

Yes
Yes
ERR
Yes
No
Yes
Yes
ERR

说明

【输入输出样例解释1】

第一个程序 i 从 1 到 1 是常数复杂度。

第二个程序 x 从 1 到 n 是 n 的一次方的复杂度。

第三个程序有一个 F 开启循环却没有 E 结束,语法错误。

第四个程序二重循环,n 的平方的复杂度。

第五个程序两个一重循环,n 的一次方的复杂度。

第六个程序第一重循环正常,但第二重循环开始即终止(因为n远大于100,100大于4)。

第七个程序第一重循环无法进入,故为常数复杂度。

第八个程序第二重循环中的变量 x 与第一重循环中的变量重复,出现语法错误②,输出 ERR

【数据规模与约定】

对于 30%的数据:不存在语法错误,数据保证小明给出的每个程序的前 L/2 行一定为以 F 开头的语句,第L/2+1 行至第 L 行一定为以 E 开头的语句,L≤10,若 x、y 均 为整数,x 一定小于 y,且只有 y 有可能为 n。

对于 50%的数据:不存在语法错误,L≤100,且若 x、y 均为整数,x 一定小于 y, 且只有 y 有可能为 n。

对于 70%的数据:不存在语法错误,L≤100。

对于 100%的数据:L≤100。

解析

T2大模拟啊。

用一个栈模拟一下就行了。

我觉得这道题就没啥可说了。

至于非法情况的维护,参照代码吧。。。。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 using namespace std;
  7 #define ll long long
  8 int t;
  9 int l;
 10 char cp[100];
 11 int s[1010],top;
 12 char ss[1010];
 13 int topp;
 14 char opt[1010];
 15 char ch,cha[5],chb[5];
 16 bool vis[100];
 17 bool err,isn;
 18 int changshu,tot,ans;
 19 int preans,mul;
 20 int len;
 21 int main(){
 22     //freopen("complexity.in","r",stdin);
 23     //freopen("complexity.out","w",stdout);
 24     scanf("%d",&t);
 25     while (t--){
 26         err=false; ans=0; tot=top=0;
 27         memset(vis,false,sizeof(vis));
 28         memset(ss,0,sizeof(ss));
 29         scanf("%d",&l);
 30         cin>>cp;
 31         //cout<<cp<<endl;
 32         len=strlen(cp);
 33         mul=1; preans=0; isn=false;
 34         for (int i=len-1;i>=0;--i){
 35             if (cp[i]>=‘0‘&&cp[i]<=‘9‘){
 36                 preans+=(cp[i]-‘0‘)*mul;
 37                 mul*=10;
 38             }
 39             if (cp[i]==‘n‘) isn=true;
 40         }
 41         while (l--){
 42             cin>>ch;
 43             while (ch==‘ ‘||ch==EOF){
 44                 cin>>ch;
 45             }
 46             //cout<<ch<<endl;
 47             if (ch==‘E‘){
 48                 if (top){
 49                     if (s[top]==1){
 50                         tot--;
 51                     }
 52                     if (ss[top]>=‘a‘&&ss[top]<=‘z‘){
 53                         vis[ss[top]-‘a‘]=false;
 54                     }
 55                     top--;
 56                 }else{
 57                     err=true;
 58                     //cout<<"error:toplack"<<endl;
 59                 }
 60             }else{
 61                 cin>>ch;
 62                 while (ch==‘ ‘){
 63                     cin>>ch;
 64                 }
 65                 //cout<<ch<<endl;
 66                 if (vis[ch-‘a‘]){
 67                     err=true;
 68                     //cout<<"error:vised"<<ch<<endl;
 69                 }
 70                 vis[ch-‘a‘]=true;
 71                 ss[top+1]=ch;
 72                 cin>>cha;
 73                 cin>>chb;
 74                 //cout<<cha<<"gg"<<chb<<endl;
 75                 if (cha[0]>=‘0‘&&cha[0]<=‘9‘&&chb[0]==‘n‘){
 76                     if (s[top]==-1){
 77                         s[++top]=-1;
 78                         continue;
 79                     }
 80                     ++tot;
 81                     //cout<<top<<endl<<tot<<endl;
 82                     ans=max(ans,tot);
 83                     s[++top]=1;
 84                 }
 85                 if (cha[0]>=‘0‘&&cha[0]<=‘9‘&&chb[0]>=‘0‘&&chb[0]<=‘9‘){
 86                     if (s[top]==-1){
 87                         s[++top]=-1;
 88                         continue;
 89                     }
 90                     len=strlen(cha);
 91                     mul=1;
 92                     int aa=0;
 93                     for (int i=len-1;i>=0;--i){
 94                         if (cha[i]>=‘0‘&&cha[i]<=‘9‘){
 95                             aa+=(cha[i]-‘0‘)*mul;
 96                             mul*=10;
 97                         }
 98                     }
 99                     len=strlen(chb);
100                     mul=1;
101                     int bb=0;
102                     for (int i=len-1;i>=0;--i){
103                         if (chb[i]>=‘0‘&&chb[i]<=‘9‘){
104                             bb+=(chb[i]-‘0‘)*mul;
105                             mul*=10;
106                         }
107                     }
108                     if (aa>bb){
109                         s[++top]=-1;
110                     }else{
111                         s[++top]=0;
112                     }
113                 }
114                 if (chb[0]>=‘0‘&&chb[0]<=‘9‘&&cha[0]==‘n‘){
115                     s[++top]=-1;
116                 }
117                 if (chb[0]==‘n‘&&cha[0]==‘n‘){
118                     s[++top]=0;
119                 }
120             }
121         }
122         if (err){
123             printf("ERR\n");
124             continue;
125         }
126         if (top){
127             printf("ERR\n");
128             //cout<<"error:topremain"<<endl;
129             continue;
130         }
131         if (ans==0){
132             if (isn==false&&preans==1) printf("Yes\n");
133             else printf("No\n");
134             continue;
135         }
136         if (ans==preans){
137             if (isn)
138                 printf("Yes\n");
139             else
140                 printf("No\n");
141             continue;
142         }else{
143             printf("No\n");
144         }
145     }
146     //fclose(stdin);
147     //fclose(stdout);
148     return 0;
149 }

时间: 2024-10-09 19:51:21

洛谷P3952 时间复杂度的相关文章

洛谷 P3952 时间复杂度

做这道题的最大收获就是坚持不懈,勇往直前,这道题是一个"码力题",不能说无脑,但绝对恶心.总共花了3h+才调出来.果然当时NOIp放弃这道题是明智的 好了,闲话放一边,我们来搞一搞这道题. 这道题思路很简单,就是模拟.t<=10和L<=100也提示了我们时间不是问题,要大胆的去模拟.我是在线判断程序是否ERR,离线判断时间复杂度计算是否正确.如果程序ERR,就标记一下,输入完之后直接结束这次循环(continue),不再进行接下来的计算.至于判断Yes和No,我先将输入的时

[题解]洛谷比赛『期末考后的休闲比赛2』

[前言] 这场比赛已经结束了有几天,但我各种忙,虽然AK但还是没来得及写题解.(我才不会告诉你我跑去学数据结构了) T1 区间方差 (就不贴题好了) 首先可以推公式(我们可以知道,线段树然而并不能通过初中学过的方差公式在log(L)内求出方差): (s2表示方差,L表示区间长度,xi表示区间的每一项,最后一个x上画了一根线表示这些数据的平均数) 用二项式定理完全平方公式可得: 再次展开: 另外,再代入以下这个 得到了: 然后继续吧.. 然后duang地一声合并同类项,于是我们得到了: 然后可以高

洛谷P1083 借教室 二分 + 差分

洛谷P1083 借教室 二分 + 差分(或说前缀和,其实前缀和更准确一点) 首先二分答案,即取 mid 个人,且他们不会冲突 然后O(n) 判断是否冲突 如何判断呢,首先我们发现 一个人的操作相当于是将 一些连续的山削去了一个高度 然后我们可以记录这座山被消了多少高度,但这样一次就要 O(N) 总共(n^2) 但是我们发现高度差只有两个地方变了,一个是起始,一个是终止 t[ i ] 表示 h[ i ] - h[ i-1 ] 改变过后 于是 t[ s ]-=d,t[ t+1 ]+=d ; 然后这样

【洛谷】【洛谷月赛】4月月赛Round 1/2

洛谷月赛"月"来"月"丧了,一月更比一月丧,做得我十分不"月"-- 4月的两轮月赛,都只会T1,就写一下吧,等待后续更新-- 先看看Round1的T1: [R1T1] 网址:点我 [题意简述] 给定一个长度为n的序列,其中的元素均是1~m之间的正整数. 要求从中选出k个数,交换它们的位置,其他未被选中的数保持不变,使得变换后的序列中,相等的数总是排在一段连续区间. 要求最小化k. 1<=n<=105,1<=m<=20 [思

洛谷P2766-最长递增子序列问题

chunlvxiong的博客 题目描述: 给定正整数序列x1,...,xn (1≤n≤500). 1.计算其最长递增子序列的长度s. 2.计算从给定的序列中最多可取出多少个长度为s的递增子序列. 3.如果允许在取出的序列中多次使用x1和xn,则从给定序列中最多可取出多少个长度为s的递增子序列. 思考&分析:  第一问应该比较easy,利用DP求解,时间复杂度O(N^2)--利用线段树可以优化到O(NlogN),但是没这个必要. 第二问:考虑使用网络流求解. 首先把所有点x拆成两个点xa,xb,每

[codevs1048]石子归并&amp;&amp;[codevs2102][洛谷P1880]石子归并加强版

codevs1048: 题目大意:有n堆石子排成一列,每次可合并相邻两堆,代价为两堆的重量之和,求把他们合并成一堆的最小代价. 解题思路:经典区间dp.设$f[i][j]$表示合并i~j的石子需要的最小代价.则有$f[i][j]=min(f[i][k]+f[k+1][j]+\sum\limits _{l=i}^{j}a[l])$,时间复杂度$O(n^3)$. C++ Code: #include<cstdio> #include<cstring> using namespace s

洛谷OJ P1141 01迷宫 解题报告

洛谷OJ P1141 01迷宫 解题报告 by MedalPluS [题目描述]    有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上.你的任务是:对于给定的迷宫,询问从某一格开始能移动到多少个格子(包含自身).   [输入描述]   输入的第1行为两个正整数n,m.  下面n行,每行n个字符,字符只可能是0或者1,字符之间没有空格.  接下来m行,每行2个用空格分隔的正整数i,j,对

洛谷P1462 通往奥格瑞玛的道路 二分答案+最短路SPFA

洛谷P1462 通往奥格瑞玛的道路二分答案+最短路SPFA 二分交费最多的一次的钱数 然后只将符合要求的边加入图中 如果到终点的最短路大于等于血量 或者直接起点不能到达终点那么说明不符合要求 需要加大答案 时间复杂度 (log答案)* Ek 需要注意如果本来就不能到达 那么直接输出AFK 1 #include <bits/stdc++.h> 2 #define LL long long 3 #define For(i,j,k) for(int i=j;i<=k;i++) 4 using

[洛谷OJ] P1114 “非常男女”计划

洛谷1114 “非常男女”计划 本题地址:http://www.luogu.org/problem/show?pid=1114 题目描述 近来,初一年的XXX小朋友致力于研究班上同学的配对问题(别想太多,仅是舞伴),通过各种推理和实验,他掌握了大量的实战经验.例如,据他观察,身高相近的人似乎比较合得来. 万圣节来临之际,XXX准备在学校策划一次大型的“非常男女”配对活动.对于这次活动的参与者,XXX有自己独特的选择方式.他希望能选择男女人数相等且身高都很接近的一些人.这种选择方式实现起来很简单.