【noip2017】时间复杂度

题目描述

小明正在学习一种新的编程语言 A++,刚学会循环语句的他激动地写了好多程序并 给出了他自己算出的时间复杂度,可他的编程老师实在不想一个一个检查小明的程序, 于是你的机会来啦!下面请你编写程序来判断小明对他的每个程序给出的时间复杂度是否正确。

A++语言的循环结构如下:

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

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


输出

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

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


样例输入

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


样例输出

Yes
Yes
ERR
Yes
No
Yes
Yes
ERR

 



题解

大模拟。主要考栈的用法。

 

#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long

int T,L,Fzd,sum,stack[1000],Maxfzd,Stack[1000],Tim,now;
char op[10],fzd[10],x[10],a[10],b[10];
bool p[1000],ERR,Notin;

template<typename T>void read(T& aa){
    char cc; ll ff;aa=0;cc=getchar();ff=1;
    while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
    if(cc=='-') ff=-1,cc=getchar();
    while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
    aa*=ff;
}

int chg(char *a){
    int len=strlen(a),ret=0;
    for(int i=0;i<len;i++)
    ret=ret*10+a[i]-48;
    return ret;
}

int main(){
    read(T);
    while(T--){
        memset(p,false,sizeof(p));sum=0;
        ERR=false;Maxfzd=0;now=0;Notin=false;
        read(L);cin>>fzd;
        if(fzd[2]=='1') Fzd=0;
        else{
            int ret=0;
            for(int i=4;;i++){
                if(fzd[i]>='0'&&fzd[i]<='9')
                ret=ret*10+fzd[i]-48;
                else break;
            }
            Fzd=ret;
        }
        for(int i=1;i<=L;i++){
            cin>>op;
            if(op[0]=='F'){
                cin>>x>>a>>b;
                if(p[x[0]]) ERR=true;
                else p[x[0]]=true;
                stack[++sum]=(int)x[0];
                if(Notin) continue;
                if(b[0]=='n'&&a[0]!='n') now++,Maxfzd=max(Maxfzd,now),Stack[sum]=1;
                else if(b[0]=='n'&&a[0]=='n') now=now,Stack[sum]=0;
                else if(chg(a)<=chg(b)) now=now,Stack[sum]=0;
                else if(chg(a)>chg(b)||(a[0]=='n'&&b[0]!='n')){
                    Notin=true;Tim=sum;
                }
            }
            else{
                p[stack[sum]]=false;
                if(Notin){
                    if(sum==Tim) Notin=false; sum--;
                    continue;
                }
                now-=Stack[sum];sum--;
            }
        }
        if(sum) ERR=true;
        if(ERR) cout<<"ERR"<<endl;
        else if(Maxfzd==Fzd) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
    return 0;
}

 

posted @ 2018-08-20 08:04  rld  阅读(477)  评论(0编辑  收藏  举报