去除掉每个串原有的匹配括号以后, 可以分成三种 1.((( 2.)))) 3.)))..((
贪心很容易将1,2放在最前和最后 对于第三种我们会希望'('比')'多的类型放在左面,同理另一种放在右面
对于3中‘(‘ 比 ’)’多的类型,‘)’多的放在后面这样‘)’会和前面的‘(’尽可能的匹配,而剩下的前面剩下的‘(’会和3里面剩下
‘)’尽可能的匹配(目前这样想的,可能有误)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
#include <algorithm>
using namespace std;
stack<int> s;
const int maxn = 1e5+10;
char str[maxn];
struct node {
int x,y;
node(int a=0,int b=0):x(a),y(b){}
}nodes[maxn];
bool cmp(node a,node b) {
if (a.x >= a.y && b.x >= b.y) return a.y < b.y;
else if (a.x >= a.y) return true;
else if (b.x >= b.y) return false;
else return a.x > b.x;
}
int main() {
int t,n;
scanf ("%d",&t);
while(t--) {
scanf ("%d",&n);
int ans = 0;
for (int i = 1; i <= n; i++) {
scanf ("%s",str);
int len = strlen(str);
nodes[i].x = 0, nodes[i].y = 0;
for (int j = 0; j < len; j++) {
if (str[j] == ')') {
if (!s.empty() && s.top() == 0) ans++, s.pop();
else nodes[i].y++;
}
else {
s.push(0);
}
}
while(!s.empty()) nodes[i].x++, s.pop();
}
sort(nodes+1,nodes+1+n,cmp);
for (int i = 1; i <= n; i++) {
int y = nodes[i].y;
for (int j = 1; j <= y; j++) {
if (!s.empty() && s.top() == 0) ans++, s.pop();
}
int x = nodes[i].x;
for (int j = 1; j <= x; j++) {
s.push(0);
}
}
while(!s.empty()) s.pop();
cout << ans*2 << endl;
}
return 0;
}