【題解】Bracket Sequence Deletion
題目連結 --> https://codeforces.com/contest/1657/problem/C
題目詳細
You are given a bracket sequence consisting of ncharacters '(' and/or )'. You perform several operations with it.
During one operation, you choose the shortest prefix of this string (some amount of first characters of the string) that is good and remove it from the string.
The prefix is considered good if one of the following two conditions is satisfied:
this prefix is a regular bracket sequence;
this prefix is a palindrome of length at least two.
A bracket sequence is called regular if it is possible to obtain a correct arithmetic expression by inserting characters '+' and '1' into this sequence. For example, sequences (())(), () and (()(())) are regular, while )(, (() and (()))( are not.
The bracket sequence is called palindrome if it reads the same back and forth. For example, the bracket sequences )), (( and )(() are palindromes, while bracket sequences (), )( and ))( are not palindromes.
You stop performing the operations when it's not possible to find a good prefix. Your task is to find the number of operations you will perform on the given string and the number of remaining characters in the string.
You have to answer t independent test cases.
Input
The first line of the input contains one integer t (1≤t≤104) — the number of test cases. The next 2 lines describe test cases.
The first line of the test case contains one integer n (1≤n≤5⋅105) — the length of the bracket sequence.
The second line of the test case contains n
characters '(' and/or ')' — the bracket sequence itself.
It is guaranteed that the sum of n over all test cases do not exceed 5⋅105 (∑n≤5⋅105).
Output
For each test case, print two integers c and r
— the number of operations you will perform on the given bracket sequence and the number of characters that remain in the string after performing all operations.
Example
Input
5
2
()
3
())
4
((((
5
)((()
6
)((()(
Output
1 0
1 1
2 0
1 0
1 1
題目大意
- 給一串只有(和)構成的字串
- 滿足括號合法 或者 有兩個以上回文字元 任何一個條件時刪除
- 輸出 運算元 和 剩餘的無法操作的字串長度
思路及程式碼實現
- 從前向後遍歷,不要求操作次數最少
- 所以一旦滿足條件則立刻刪除,((((即算作兩次操作
- 對於合法的括號匹配,實際上只有()這一種可能、其他的巢狀則按照迴文處理
- 比如(( ))則按照兩次迴文處理,而不是一次巢狀括號
- 所以,事實上只有兩種可能
- 左括號(:可以和任意字元匹配刪除
- 右括號):只能找到下一個)時按照迴文的規則刪除
C++程式碼實現
#include <iostream>
#include <algorithm>
using namespace std;
int n, ans;
string str;
char ch;
int main(){
int t;
cin >> t;
while (t--){
ans = 0;
cin >> n;
getchar();
for (int i = 0; i < n; i++){
cin >> ch;
str += ch;
if (str == "()" || (str.size() >= 2 && str[str.size() - 1] == str[0])){
ans++;
str.clear();
}
}
cout << ans <<' '<<str.size() << endl;
}
return 0;
}