给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;
}