洛谷

https://www.luogu.org/problemnew/show/P3952
这个模拟,注意每次进入循环的时候把新状态全部入栈,退出循环的时候就退栈。
第一次就错在发现ERR退出太及时,把剩余的信息留在流里面。

所以下次还是全部保存在字符串里面就好。一次下载一整段程序。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;


void solve() {
    int l;
    scanf("%d",&l);
    char fzds[20];
    scanf("%s",fzds);
    int on=0;
    if(fzds[3]!='^')
        ;
    else {
        for(int i=4; fzds[i]!=')'; i++) {
            on=on*10+fzds[i]-'0';
        }
    }
    //变量进栈的顺序
    stack<char> chs;
    //被占用的变量的标记

    stack<bool> onplus;
    bool used[256]= {};
    int cnt=0;

    //当前的时间复杂度是n的几次方?
    int curon=0;
    //曾经到过的最高的复杂度
    int maxon=0;

    //当前是否能运行至少一次,每次与栈顶取与之后放进去
    stack<bool> currun;
    currun.push(true);

    int res=1;

    int i;
    for(i=0; i<l; i++) {
        char ins[20];
        scanf("%s",ins);
        if(ins[0]=='E') {
            cnt--;
            if(cnt<0) {
                //E比F还多
                res=-1;
                continue;
            }
            char ch=chs.top();
            chs.pop();
            used[(int)ch]=0;
            if(onplus.top()==true) {
                curon--;
            }
            onplus.pop();
            currun.pop();
        } else {
            //是F,栈顶++
            cnt++;
            char ch[20];
            scanf("%s",ch);
            if(used[(int)ch[0]]) {
                //变量名冲突
                res=-1;
            }
            //变量名没有冲突
            used[(int)ch[0]]=1;
            chs.push(ch[0]);

            char s1[40],s2[40];
            scanf("%s%s",s1,s2);
            if(s1[0]=='n') {
                //第一个变量是n,不可能增加复杂度
                onplus.push(false);
                if(s2[0]=='n') {
                    //至少进入1次,push一个成功标记
                    currun.push(true&currun.top());
                } else {
                    //n比常数要大,push一个不行
                    currun.push(false);
                }
            } else {
                //第一个不是n
                if(s2[0]=='n') {
                    //第2个是n,当外层循环可以进入的时候复杂度+1
                    if(currun.top()) {
                        curon++;
                        maxon=max(curon,maxon);
                        onplus.push(true);
                        currun.push(true);
                    } else {
                        //外面不能进入这里
                        onplus.push(false);
                        currun.push(false);
                    }
                } else {
                    //两个都不是n
                    onplus.push(false);
                    //常数时间

                    int t1=0,t2=0;
                    for(int j=0; s1[j]!=''; j++) {
                        t1=t1*10+s1[j]-'0';
                    }
                    for(int j=0; s2[j]!=''; j++) {
                        t2=t2*10+s2[j]-'0';
                    }

                    //进入不了
                    if(t1>t2) {
                        currun.push(false);
                    } else {
                        //至少进入一次
                        currun.push(true&currun.top());
                    }
                }
            }
        }
    }

    if(res==-1) {
        puts("ERR");
        return;
    }

    if(cnt) {
        //有F没结束
        puts("ERR");
        return;
    } else {
        if(on==maxon) {
            puts("Yes");
        } else {
            puts("No");
        }
    }
}

int main() {
#ifdef Yinku
    freopen("Yinku.in","r",stdin);
#endif // Yinku
    int t;
    scanf("%d",&t);
    while(t--) {
        solve();
    }
}
原文地址:https://www.cnblogs.com/Yinku/p/11018282.html