C. Bracket Sequence Deletion
题目连接
题意:给一个长度为n只由 (
和 )
组成的字符串,每次删除一个长度最短的前缀串(从第一个开始连续串),删除需要满足以下要求
- 1,是一个合法的括号串,即
(())()
,()
,(()(()))
- 2,满足回文串且长度大于等于2 , 即
((
,))
,)(()
直到不能删除为止,输出删除次数和剩下的字符个数
思路:起初想的暴力做法,毫无疑问t掉了,那么是否有一些性质存在呢,既然要求每次删除的要求长度最短,那么最短的有四种情况()
, ((
, ))
,)(
,前三种都是满足要求可以直接删除的,对于最后一种继续扩展,可以添加一个左括号或者右括号,如果是一个)
, 显然可以组成一个回文串,否则就是添加一个(
,这时情况显然等同于上次,添加)
形成回文串。
// Problem: C. Bracket Sequence Deletion
// Contest: Codeforces - Educational Codeforces Round 125 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1657/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int mod=1000000007;
const double eps=1e-8;
bool hw(string s)
{
string s1 = s;
reverse(s.begin() , s.end());
if(s1 == s && s.size() >= 2) return true;
return false;
}
int main(){
ios
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
string s;
cin>>s;
int cnt = 0;
queue<char> qu;
bool flag = true;
int sum = n;
string s1 = "";
for(int i = 0 ; i < s.size() ; i ++ )
{
s1 += s[i];
if(s1 == "()" || s1 == "((" || s1 == "))")
{
s1 = "";
sum -= 2;
cnt ++;
}
else if(s1.size() >= 2)
{
if(s[i] == ')')
{
sum -= s1.size();
s1 = "";
cnt ++;
}
}
}
cout<<cnt<<" "<<sum<<"\n";
}
return 0;
}