题意:
给你n个括号字符串,让你自由组合这n个字符串,首尾相连。问你最长的括号匹配长度是多少。
POINT:
先把字符串处理了,把()的成功匹配的删掉。
剩下的字符串就只有3种:
1、))))
2、((((
3、)))(((。
所以第一种放在最后面,第2种放在最前面。
只剩第三种了。把”(“数量大于”)“的字符串成为正字符串,反之为负字符串。正字符串必定排在负字符串前面
正字符串中)少的排在前面。负字符串(多的排在前面。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <algorithm>
#define LL long long
using namespace std;
stack<int> q;
const int maxn = 1e5+44;
struct node
{
int l,r;
}a[maxn];
char s[maxn];
bool cmp (node a,node b)
{
if(a.l>=a.r&&b.l<b.r) return true;
if(a.l<a.r&&b.l>=b.r) return false;
if(a.l>=a.r&&b.l>=b.r) return a.r<b.r;
return a.l>b.l;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
int n;scanf("%d",&n);
int ans=0;
for(int i=1;i<=n;i++){
scanf("%s",s);
int l=strlen(s);
int ll=0,rr=0;
for(int j=0;j<l;j++){
if(s[j]=='(') q.push(0);
else{
if(!q.empty()){
q.pop();
ans+=2;
}else{
rr++;
}
}
}
while(!q.empty()){
ll++;
q.pop();
}
a[i].l=ll;
a[i].r=rr;
}
sort(a+1,a+1+n,cmp);
//for(int i=1;i<=n;i++)
// printf("%d %d\n",a[i].l,a[i].r);
int l=0;
for(int i=1;i<=n;i++){
if(l>=a[i].r){
ans+=2*a[i].r;
l-=a[i].r;
}else{
ans+=2*l;
l=0;
}
l+=a[i].l;
}
printf("%d\n",ans);
}
return 0;
}