Educational Codeforces Round 45 (Rated for Div. 2) C. Bracket Sequences Concatenation Problem (模拟)

原题地址:http://codeforces.com/contest/990/problem/C

题意:给出n个字符串,字符串仅有’(‘和’)’,询问有多少对字符串可以组成完美匹配的括号。

思路: 先考虑当前已经是匹配的括号的时候,那么如果要再加一个字符串形成匹配括号的话,那么只能和同样是已经匹配的配对。所以假设有x个完美匹配的字符串,那么就应该会有 x 2 中方法。

那么如果当前是不匹配的话,就也是只能找不匹配的。然而不同的是,如果你当前缺少a个右括号,那么相应要匹配的应该是要多a个右括号。然后缺少的方案数*多的方案数,最后相加即可。

注意处理一个字符串无论如何都不能形成完美匹配的情况。(比如说 “)(“)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
int n;
const int maxn = 3e5 + 5;
ll a[maxn], b[maxn]; //a是左括号,b是右括号,c是已经相等的
char str[maxn];
void check(char *s) {
    int len = strlen(s + 1);
    int flag = 0; //0为左
    int left = 0;
    int right = 0;
    for(int i = 1; i <= len; i++) {
        if(s[i] == '(') left++;
        else if(s[i] == ')') right++;
        if(right > left) flag = 1;
    }
    if(flag){//对于只能是在右边的情况再倒着判断是否合法
        int x=0;
        int y=0;
        for(int i=len;i>=1;i--){
            if(s[i]=='(') x++;
            else y++;
            if(x>y) return;
        }
    }
    if(flag) b[right - left]++;

    else   a[left - right]++;
}
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%s", str + 1);
        check(str);
    }

    ll ans =  a[0]*a[0];
    for(int i = 1; i <= 3e5; i++) ans +=  a[i] * b[i];
    cout << ans << endl;
    return 0;
}

//网上大神的代码,思路要比我的清晰一点
#include <bits/stdc++.h>
using namespace std;
int n;
typedef long long ll;
const int maxn = 3e5 + 5;
ll a[maxn], b[maxn];
char str[maxn];
int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%s", str + 1);
        int len = strlen(str + 1);
        int left = 0;
        int right = 0;
        for(int i = 1; i <= len; i++) {//注意这里
            if(str[i] == '(') left++;
            else {
                if(left) left--;
                else right++;
            }
        }
        if(left == 0) b[right]++;
        if(right == 0) a[left]++;
    }
    ll ans = 0;
    for(int i = 0; i <= 3e5; i++ ) ans += a[i] * b[i];
    printf("%I64d\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/80760554