题意:
给你一个只包含 '(' 和 ')' 的长度为 n 字符序列s;
给出一个操作:将第 i 个位置的字符反转('(' ')' 互换);
问有多少位置反转后,可以使得字符串 s 变为"Regular Bracket Sequence";
输出满足条件的位置的个数;
题解:
令 '(' = 1 , ')' = -1;
定义 sum[i]:括号序列的前缀和;
一个合法的括号匹配串的充要条件是:
[1] 对于任何 i,sum[i] ≥ 0;
[2] sum[n]=0;
1 int n; 2 char s[maxn]; 3 int sum[maxn];///前缀和 4 int a[maxn];///a[i]:min{sum[1,..,i]} 5 int b[maxn];///b[i]:min{sum[i,..,n]}
枚举位置 i,判断将位置 i 反转后序列是否变为 "Regular Bracket Sequence";
1 ///i位置反转只会影响[i,n]的sum值 2 ///首先要确保[1,i-1]序列满足条件[1] 3 ///接着判断将i位置反转后 4 ///①sum[n]±2是否为0 5 ///②b[i]±2是否≥0 6 bool isSat(int i)///判断i位置反转后序列是否可以变为RBS 7 { 8 if(a[i-1] < 0) 9 return false; 10 if(s[i] == ')') 11 return b[i]+2 >= 0 && sum[n]+2 == 0 ? true:false; 12 else 13 return b[i]-2 >= 0 && sum[n]-2 == 0 ? true:false; 14 }
AC代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define INF 0x3f3f3f3f 4 const int maxn=1e6+50; 5 6 int n; 7 char s[maxn]; 8 int sum[maxn]; 9 int a[maxn]; 10 int b[maxn]; 11 12 ///i位置反转只会影响[i,n]的sum值 13 ///首先要确保[1,i-1]序列满足条件[1] 14 ///接着判断将i位置反转后 15 ///①sum[n]±2是否为0 16 ///②b[i]±2是否≥0 17 bool isSat(int i)///判断i位置反转后序列是否可以变为RBS 18 { 19 if(a[i-1] < 0)///[1,i-1]不满足条件[1] 20 return false; 21 if(s[i] == '(')///'('变为')' i及其之后的sum-2 22 return b[i]-2 >= 0 && sum[n]-2 == 0 ? true:false; 23 else 24 return b[i]+2 >= 0 && sum[n]+2 == 0 ? true:false; 25 } 26 int Solve() 27 { 28 sum[0]=0; 29 for(int i=1;i <= n;++i) 30 sum[i]=sum[i-1]+(s[i] == '(' ? 1:-1); 31 32 a[0]=INF; 33 for(int i=1;i <= n;++i) 34 a[i]=min(sum[i],a[i-1]); 35 b[n+1]=INF; 36 for(int i=n;i >= 1;--i) 37 b[i]=min(sum[i],b[i+1]); 38 39 int ans=0; 40 for(int i=1;i <= n;++i) 41 if(isSat(i)) 42 ans++; 43 44 return ans; 45 } 46 int main() 47 { 48 scanf("%d%s",&n,s+1); 49 printf("%d ",Solve()); 50 51 return 0; 52 }