Description
给定括号长度N,给出一串括号(只包含小括号),计算出最少的交换(两两交换)次数,使整个括号序列匹配。
我们认为一个括号匹配,即对任意一个')',在其左侧都有一个'('与它匹配,且他们形成一一映射关系。
Format
Input
第一行:整数N,表示括号序列长度
第二行:一个字符串,表示括号
Output
一个整数,表示最少的交换次数
Sample
Input1
6
(()))(
Copy
Output1
1
Copy
Input2
6
)))(((
Copy
Output2
2
#include <bits/stdc++.h>
using namespace std;
const int maxn=5e6+5;
char a[maxn];
stack<char>s;
int main()
{
int n;
while(cin>>n){
while(!s.empty())
s.pop();
cin>>a;
int cnt=0;
for(int i=0;i<n;i++){
if(a[i]=='(')
s.push('(');
else{
if(s.empty()||s.top()==')')
s.push(')');
else{
s.pop();
cnt++;
}
}
}
cout<<(n/2-cnt+1)/2<<endl;
}
return 0;
}
我们的cnt计算出的是已经匹配了的两个左括号和右括号,n-cnt*2等于未匹配的括号,比如)))(((或者))((
(这个时候可以不考虑具体位置,只需要知道相对位置即可),最后一定只有两种情况,
1) 相对的方向,)))(((
2) 同向)))))) (通过分析,也不可能,因为一定存在一般的左括号和右括号)
我们需要对一般的数据进行操作就可以了,因为是对称,我们只需要分析一下))((和)))(((,即n-cnt*2的一半是奇数个和偶数个的情况就可以了。