Balanced Sequence
Problem Description
Chiaki has strings consisting of ‘(’ and ‘)’. A string of this type is said to be balanced:
- if it is the empty string
- if and are balanced, is balanced,
- if is balanced, is balanced.
Chiaki can reorder the strings and then concatenate them get a new string . Let be the length of the longest balanced subsequence (not necessary continuous) of . Chiaki would like to know the maximum value of for all possible .
Input
There are multiple test cases. The first line of input contains an integer , indicating the number of test cases. For each test case: The first line contains an integer ( ) – the number of strings. Each of the next lines contains a string ( ) consisting of (' and
)’. It is guaranteed that the sum of all does not exceeds .
Output
For each test case, output an integer denoting the answer.
Sample Input
2
1
)()(()(
2
)
)(
Sample Output
4
2
題目概述
有n行只包含左右括號的字符串,問如何連接這些字符串可以使得匹配到的括號最多(包括本行自身含有的“()”)
解題思路
我們先算每一行字符串中含有的成對的(),並在該行中刪除已配對過的“(” 和 “)”
進行完以上操作我們可以發現每行數組都只剩下多個“)” “(”。且)全在左邊,(全在右邊。(每個字符串都這麼處理後剩下都爲“)))((((((”結構的括號串。)
那麼我們把剩下的字符串拼接
要想匹配到的括號最多,則儘量讓每個括號都起作用了;
如果只包含左括號則把他放在最前邊,如果只有右括號把他放在最後邊;
可以看出左括號多於右括號的在前,反之在後;
同是左括號多於右括號的,右括號少的在前;
同是右括號多於左括號的,左括號少的在後;
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int mmax=1e5+7;
char st[mmax];
struct node
{
int l,r;
}a[mmax];
bool cmp(node x,node y)
{
if (x.r >= x.l && y.r < y.l)
return false;
if (x.r < x.l && y.r >= y.l)
return true;
//')'比'('多的放後面
//')'比'('少 比較')'少的放前面 ')'比'('多 比較'('少的放後面
if (x.r < x.l && y.r < y.l)
return x.r<y.r;
else return x.l>y.l;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,sum=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",st);
int len=strlen(st);
a[i].l=0;
a[i].r=0;
for(int j=0;j<len;j++)
{
if(st[j]==')')
{
if(a[i].l<=0)
a[i].r++; //沒有緊鄰的(來配對,( 數量加一
else
{
a[i].l--; //有可以配對的(,消耗一個)。
sum++; //配對成功的組數加一
}
}
else
a[i].l++;
}
}
sort(a,a+n,cmp);
int l=0; //l表示剩餘的“(”數
for(int i=0;i<n;i++)
{
if(a[i].r<=l)
{
sum+=a[i].r;
l-=a[i].r; //l減少了a[i].r個,用於配對了
}
else
{
sum+=l;
l=0; //l都用了配對了
}
l+=a[i].l; //a[i]組字符串右邊全是(
}
printf("%d\n",sum*2);
}
return 0;
}