加载中...

一些难题

给n个括号,需要排好序保证这个序号是有序的

#include <bits/stdc++.h>

using namespace std;

const int N = 10010;

int n;
struct Seq
{
    int l, r, d, id;//id记录第几个,d记录左减去右边相差的值,
    string s;
}seq[N];

// 自定义比较函数
bool cmp(Seq &a, Seq &b)
{
    if (a.d >= 0 && b.d < 0 || a.d < 0 && b.d >= 0) return a.d >= 0;//d大于0放左边
    else if (a.d >= 0) return a.r < b.r;
//r小的放左边
    else return a.l > b.l;
//l大的放左边
}

// 检查是否为一个合法的括号序列
bool check()
{
    int t = 0;
    for (int i = 1; i <= n; i ++ )
    {
        t -= seq[i].r;//对于排好序的第一个序列,如果还有r需要排序的右括号就肯定不会成功;对后面的序列,前面一定会留下待排好序的左括号,再减去就可以了,
        if (t < 0) return false;
        t += seq[i].l;//遇到待匹配的左括号就就+
    }
    return !t;//t最后会变成0
}

int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        int l = 0, r = 0;
        string str;
        cin >> str;

        // 计算待消耗的左括号和右括号
        for (auto u : str)
            if (u == '(') l ++ ;
            else
            {
                if (l) l -- ;
                else r ++ ;
            }
        seq[i] = {l, r, l - r, i, str};//i记录第几个序列,使用数组seq存储每个序列
    }

    sort(seq + 1, seq + 1 + n, cmp);
//对这个数组进行排序
    if (check())
    {  // 如果是个合法序列,则输出一个排列
        cout << "YES\n";
        for (int i = 1; i <= n; i ++ ) cout << seq[i].id << ' ';
        cout << '\n';
    }
    else cout << "NO\n";
    return 0;
}



posted @ 2021-12-12 16:14  liang302  阅读(27)  评论(0编辑  收藏  举报