Codeforces 990C (思维)

传送门

题面:

    

C. Bracket Sequences Concatenation Problem
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

A bracket sequence is a string containing only characters "(" and ")".

A regular bracket sequence is a bracket sequence that can be transformed into a correct arithmetic expression by inserting characters "1" and "+" between the original characters of the sequence. For example, bracket sequences "()()", "(())" are regular (the resulting expressions are: "(1)+(1)", "((1+1)+1)"), and ")(" and "(" are not.

You are given nn bracket sequences s1,s2,,sns1,s2,…,sn. Calculate the number of pairs i,j(1i,jn)i,j(1≤i,j≤n) such that the bracket sequence si+sjsi+sj is a regular bracket sequence. Operation ++ means concatenation i.e. "()(" + ")()" = "()()()".

If si+sjsi+sj and sj+sisj+si are regular bracket sequences and iji≠j, then both pairs (i,j)(i,j) and (j,i)(j,i) must be counted in the answer. Also, if si+sisi+si is a regular bracket sequence, the pair (i,i)(i,i) must be counted in the answer.

Input

The first line contains one integer n(1n3105)n(1≤n≤3⋅105) — the number of bracket sequences. The following nn lines contain bracket sequences — non-empty strings consisting only of characters "(" and ")". The sum of lengths of all bracket sequences does not exceed 31053⋅105.

Output

In the single line print a single integer — the number of pairs i,j(1i,jn)i,j(1≤i,j≤n) such that the bracket sequence si+sjsi+sj is a regular bracket sequence.

Examples
input
Copy
3
)
()
(
output
Copy
2
input
Copy
2
()
()
output
Copy
4
Note

In the first example, suitable pairs are (3,1)(3,1) and (2,2)(2,2).

In the second example, any pair is suitable, namely (1,1),(1,2),(2,1),(2,2)(1,1),(1,2),(2,1),(2,2).

题目描述:

    给你n个总长度不超过3e5的“)”或“(”的字符串。当存在完整的括号“()”,则称这是完美的括号。问你从这n个选任意两个字符串并将它们相加,最多能构成多少个完美的括号。

题目分析:

    首先我们可以观察到,对于每一个字符串,我们将从左到右将“(”和“)”括号进行匹配。倘若剩下的括号既有“(”又有“)”,则存在且仅存在“)(”这种字符串。而我们很容易发现,这种字符串是不可能进行匹配的,因此我们只需要排除掉这种情况即可。

    而倘若不存在上述的情况,我们不难发现,此时必定仅剩下一种符号。此时,我们可以开一个桶num[i][j],使得num[i][j]++,表示j个第i种括号的数量+1。

    统计完这些数据之后,我们只需从头遍历到n个字符串中最大的长度len,每一次将num[0][len]*num[1][len](假设0代表“(”;1代表“)”)加到结果去即可。

代码:

#include <bits/stdc++.h>
#define maxn 300005
using namespace std;
typedef long long ll;
ll num[2][maxn];
int main()
{
    int n;
    string str;
    cin>>n;
    ll res=0;
    for(int i=0;i<n;i++){
        cin>>str;
        int len=str.length();
        ll l=0,r=0;
        for(int j=0;j<len;j++){
            if(str[j]==')'){
                if(l) l--;//如果匹配到右括号而前面出现过左括号则左右括号匹配
                else r++;//如果匹配不出来,则右括号+1
            }
            else l++;
        }
        if(l&&r) continue;//如果左右括号均有剩余,则只可能出现“)(”的情况
        if(l){
            num[0][l]++;//剩余l个左括号匹配,使桶的数量+1
        }
        else if(r){
            num[1][r]++;
        }
        else res++;//完全匹配
    }
    res*=res;//使得完全匹配能够翻倍
    for(int i=1;i<maxn;i++){//统计0到最大长度的数量
        res+=num[0][i]*num[1][i];
    }
    cout<<res<<endl;
}

猜你喜欢

转载自blog.csdn.net/weixin_39453270/article/details/80691895