小白月赛76 E.括号序列操作专家

若左括号的数量与右括号的数量不相等,那么无解。

如果有解,以下是其中一种最优策略:

对于每一个左括号:

  • 如果他的左边有未配对的右括号,那么把这个左括号直接移动到最左边的未配对右括号的左边与之配对;
  • 否则,他只能跟右边的右括号配对。

对于每一个右括号:

  • 如果左边有未配对的左括号,那么直接将这个右括号和左边未配对的左括号配对即可;否则,它只能后续跟右边的左括号配对。

记录当前左右括号的数量,和当前未配对右括号的数量即可。

下面是c++代码:

#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
 
void solve() {
    int n;
    cin >> n;
    string s;
    cin >> s;
     
    vector<bool> used(n);
    ll op = 0;
    int diff = 0;
    int p = 0;
    int cnt1 = 0, cnt2 = 0;
    for (int i = 0; i < n; i++) {
        if (!used[i]) {
            if (s[i] == '(') diff++;
            else diff--;
            if (diff < 0) {
                if (p <= i) p = i + 1;
                while (p < n && s[p] == ')') p++;
                if (p == n) {
                    cout << -1 << endl;
                }
                op += p - i - cnt2 + cnt1;
                used[p] = true;
                p++;
                cnt2++;
                diff++;
            }
        }
        else cnt1++;
    }
     
    if (diff == 0) cout << op << endl;
    else cout << -1 << endl;
}
 
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
     
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
     
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值