【题解】NOIP2017 D1T2时间复杂度

题解 NOIP2017 D1T2时间复杂度

loj 洛谷

题意:给一个简化的只有循环的代码,计算时间复杂度。

模拟,本人码力很差,陆陆续续调了好几天才出来。。

用一个栈模拟循环,遇到 F 入栈,遇到 E 出栈。

语法错误的情况就维护一个 used 数组记录用没用过这个变量,而且当遇到 E 但是栈已经空了又或者程序结束栈还不是空的就报错。

怎样维护循环无法进行的情况?(要注意,\(x=y=n\) 的情况也无法进行循环)

可以把 used 数组的值设为这个循环的层数,当无法执行循环的时候就设置一个变量 brk ,记录为再哪一层循环中断了,等到出栈的时候如果又回到了那一层就可以把 brk 再设为 0 了。

#include<bits/stdc++.h>
using namespace std;
int used[50];
int t, l;
string O;
struct cmd
{
    string type, i, x, y;
};
stack<cmd> s;
int main()
{
    ios::sync_with_stdio(false);
    cin >> t;
    while (t--)
    {
        int ON = 0, brk = 0, ceng = 0;
        bool if_ERR = 0;
        while (!s.empty()) 
            s.pop();
        memset(used, 0, sizeof(used));
        cin >> l >> O;
        int cnt = 0;
        string x, y, p, i;
        for (int k = 0; k < l; k++)
        {
            cin >> p;
            if (p[0] == 'F')
            {
                cin >> i >> x >> y;
                if (if_ERR) continue;
                if (used[i[0] - 'a']) // 变量用过了
                {
                    cout << "ERR\n";
                    if_ERR = 1;
                    continue;
                }
                used[i[0] - 'a'] = ++ceng;
                if (isdigit(x[0]) && y == "n" && !brk)
                    ON++;
                else if (x == "n" && isdigit(y[0]) && !brk)
                    brk = ceng;
                else if (!brk && isdigit(x[0]) && isdigit(y[0]) && stoi(x) > stoi(y))
                    brk = ceng;
                s.push((cmd) { "F", i, x, y });
            }
            else
            {
                if (if_ERR)
                    continue;
                cmd now;
                if (s.empty())
                {
                    cout << "ERR\n";
                    if_ERR = 1;
                    continue;
                }
                else
                {
                    now = s.top();
                    s.pop();
                }
                ceng--;
                if (used[now.i[0] - 'a'] == brk)
                    brk = 0;
                cnt = max(ON, cnt);
                if (!brk && isdigit(now.x[0]) && now.y == "n")
                    ON--;
                used[now.i[0] - 'a'] = 0;
            }
        }
        if (if_ERR == 1)
            continue;
        else if (!s.empty())
        {
            cout << "ERR" << endl;
        }
        else if (cnt == 0)
        {
            if (O == "O(1)")
                cout << "Yes" << endl;
            else
                cout << "No" << endl;
        }
        else if (cnt != 0)
        {
            string ans = "O(n^" + to_string(cnt) + ")";
            if (ans == O)
                cout << "Yes\n";
            else
                cout << "No\n";
        }
    }
    return 0;
}
posted @ 2021-04-02 22:01  _slb  阅读(57)  评论(0编辑  收藏  举报