思路
分别枚举连续子序列所有起点的可能。
用变量来记录左括号和右括号的数量,左括号 \(+1\),右括号 \(-1\)。
对于问号,则通过当前左括号和右括号的数量来判断应该变为右括号还是变为左括号。
当右括号数量大于左括号数量时,就可以停止枚举以当前起点为起点的连续子序列了,因为无论怎么枚举都是不合法的。
如果当前子序列内的左括号与右括号数量相等,则让答案加一。
AC 代码
#include<bits/stdc++.h>
using ll = long long;
using namespace std;
string s;
int cnt,ans,flag;int main(){// freopen("text.in","r",stdin);// freopen("text.out","w",stdout);ios::sync_with_stdio(0),cout.tie(0),cin.tie(0);cin >> s;int n = s.size();for(int i = 0; i < n;i++){cnt = 0;flag = 0; for(int j = i; j < n;j++){if(s[j] == '(')cnt++;if(s[j] == ')')cnt--;if(s[j] == '?'){if(cnt > 0)cnt--,flag++;else cnt++;} if(cnt == 0)ans++;else if(cnt < 0){if(flag){cnt += 2;flag--;}else{break; }}} } cout<<ans;return 0;
}