题意:输入一些字符串,只含有左右括号,当且仅当两字符串的合成体左右括号数量相同且最左边是左括号,最右边是右括号时,字符串可组合,字符串只能用一次。求最大组合数。
题解,可以先处理"()"的情况。处理字符串中部分回文的情况,可以使用栈解决。
处理完后:1.如果只有'(',与有相同数量的')'的串组合。
如果是空串,空串计数器+1,如果两种都有,不可能组合。
数量就是空串数除2取整+左右括号数对应的串数的较小值的加和。
AC代码:
#include <iostream>
#include <cstdio>
#include <stack>
#include <string>
#include <cstring>
#define min(a,b) (a>b?b:a)
using namespace std;
const int MAXN = 5e5 + 5;
int non = 0, l[MAXN], r[MAXN];
char tmp[MAXN];
int main()
{
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i)
{
scanf("%s", tmp);
int len = strlen(tmp);
int ll= 0, rr = 0;
stack<char>s;
for (int j = 0; j < len; ++j)
{
if (s.empty())
s.push(tmp[j]);
else if (s.top() == '(' && tmp[j] == ')')
s.pop();
else
s.push(tmp[j]);
}
while (!s.empty())
{
if (s.top() == '(')
++ll;
else
++rr;
s.pop();
}
if (ll + rr == 0)
++non;
else if (ll > 0 && rr == 0)
++l[ll];
else if (ll == 0 && rr > 0)
++r[rr];
}
int ans = 0;
for (int i = 0; i < MAXN; ++i)
ans += min(l[i], r[i]);
ans += non / 2;
printf("%d\n", ans);
return 0;
}