1 条题解

  • 0
    @ 2026-10-26 13:00:02

    思路与算法

    对每行用栈保存尚未匹配的左括号,定义等级<>为0、()为1、[]为2、{}为3。读左括号时,如果它的等级比当前栈顶更大,就违反内到外的规定;否则压栈。读右括号时必须与栈顶同种,随后弹栈。最终没有违反规则且栈为空才输出YES。

    正确性说明

    栈顶是最近尚未匹配的左括号,右括号只能与它匹配,保证括号正确配对且不交叉。新内层等级不能大于外层等级,恰好落实题目规定;相同种类可以嵌套,公开样例中的{{}}等对此有证据。相邻独立括号段在栈清空后互不限制。全部扫描完栈为空等价于没有缺失右括号,结合前述条件即为合法。

    复杂度

    每字符最多入栈一次、出栈一次。设各行长度L_i,总时间O(ΣL_i+组数),每行栈空间O(L_i),最多255。逐行栈和标志初始化O(1),字符缓冲的读取与末尾CR清理包含在总时间内。

    易错点

    普通括号匹配不足以判定本题,([])虽配对却违反层级;([)]是交叉匹配错误。<>必须位于更高等级内层。空字符串按空匹配处理。每行输出独立结论,不能把上一行未清空的栈带入下一行。

    参考代码(C++11)

    #include <bits/stdc++.h>
    using namespace std;
    int level(char c) {
        if (c == '<' || c == '>')
            return 0;
        if (c == '(' || c == ')')
            return 1;
        if (c == '[' || c == ']')
            return 2;
        return 3;
    }
    int main() {
        string count;
        getline(cin, count);
        string s;
        while (getline(cin, s)) {
            if (!s.empty() && s.back() == '\r')
                s.pop_back();
            vector<char> st;
            bool ok = true;
            for (char c : s) {
                int k = level(c);
                if (c == '<' || c == '(' || c == '[' || c == '{') {
                    if (!st.empty() && k > level(st.back()))
                        ok = false;
                    st.push_back(c);
                } else if (st.empty() || level(st.back()) != k)
                    ok = false;
                else
                    st.pop_back();
            }
            cout << (ok && st.empty() ? "YES" : "NO") << '\n';
        }
    }
    
    • 1

    信息

    ID
    1732
    时间
    1000ms
    内存
    64MiB
    难度
    进阶
    标签
    递交数
    1
    已通过
    1
    上传者