C++:HDU6299 Balanced Sequence

Balanced Sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5405    Accepted Submission(s): 1398

 

Problem Description

Chiaki has n strings s1,s2,…,sn consisting of '(' and ')'. A string of this type is said to be balanced:

+ if it is the empty string
+ if A and B are balanced, AB is balanced,
+ if A is balanced, (A) is balanced.

Chiaki can reorder the strings and then concatenate them get a new string t. Let f(t) be the length of the longest balanced subsequence (not necessary continuous) of t. Chiaki would like to know the maximum value of f(t) for all possible t.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1≤n≤105) -- the number of strings.
Each of the next n lines contains a string si (1≤|si|≤105) consisting of `(' and `)'.
It is guaranteed that the sum of all |si| does not exceeds 5×106.

Output

For each test case, output an integer denoting the answer.

Sample Input

2
1
)()(()(
2
)
)(

Sample Output

4
2

Source

2018 Multi-University Training Contest 1

题目大意:t 组测试,输入 n 表示接下来输入 n 行由 "(" 和 ")" 组成的字符串,求的是把这些字符串按一定顺序排列,使尽量多的括号前后匹配,最多可以匹配的括号的个数(是个数,不是对数)

解题思路:这是2018暑假多校联赛的第二题,当时比赛时并没有做出来,这还是在参考了多篇大佬的博客后写代码。每串字符在输入后就进行判断,把已经可以匹配的括号消掉并计入结果,然后剩下的就是全是类似于 "))))((((" 这种样样式的字符串,有两种特殊的就是:左括号或者右括号个数为 0,然后再对剩下的字符串排序,再进行匹配,求匹配的个数。重点是这个排序规则。

代码:

/*
两个相比")"比"("多的放后面

两个都是")"比"("少---")"少的放前面

两个都是")"比"("多---"("少的放后面
*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
struct node//用来记录第一次匹配后剩下的左右括号个数
{
    int l;
    int r;
}s[maxn];
bool cmp(node a,node b)
{
    if(a.r>=a.l&&b.r<b.l)
        return false;
    if(a.r<a.l&&b.r>=b.l)
        return true;
    if(a.r<a.l&&b.r<b.l)
        return a.r<b.r;
    else
        return a.l>b.l;
}
int main()
{
    char str[maxn];
    int t,n,ans;
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
           scanf("%s",str);
           s[i].l=0;s[i].r=0;
           for(int j=0;j<strlen(str);j++)
           {
               if(str[j]=='(')
                    s[i].l++;
               else
               {
                   if(s[i].l) s[i].l--,ans++;
                   else  s[i].r++;
               }
           }
        }
        sort(s,s+n,cmp);
        int l=0;
        for(int i=0;i<n;i++)
        {
            if(s[i].r<=l)
                ans+=s[i].r,l-=s[i].r;//有s[i].r对括号配对
            else
                ans+=l,l=0;//l全部配对
            l+=s[i].l;
        }
        printf("%d\n",ans*2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40907345/article/details/81388718