CF-div2-626-C.Unusual Competitions
法一:
1.容易想到,左括号不等于右括号数量,就不行,输出-1
2.转成括号序列问题,遇到左括号+1,遇到右括号-1;
然后括号匹配,当前缀和为0的时候为合法序列。前缀和为负的时候为“可以更改成合法的非法序列”
参考思路
法二:
搞个栈,贪心
1.容易想到,左括号不等于右括号数量,就不行,输出-1
2.每次遇到右括号 弹出栈顶左括号;如果遇到右括号,前面栈中却没有左括号,说明这个序列需要我们去更改。比如)(
如果每次遇到右括号前面都有左括号与它匹配就是个合法的括号,权值为0;比如(()())
思路2代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+100;
int n;
char s[maxn];
stack<char> st;
int main(){
cin>>n;
int allLeft = 0,allRight = 0;
for(int i=1;i<=n;i++) {
cin>>s[i];
if(s[i] == '(') allLeft++;
else allRight++;
}
if(allLeft != allRight){
puts("-1");
return 0;
}
int left = 0,right = 0;
int ans = 0;
bool flag2 = true;
for(int i=1;i<=n;i++){
if(s[i] == '(') {
left++;
st.push('(');
}
else {
//每次遇到右括号 弹出栈顶左括号
//如果遇到右括号,前面栈中却没有左括号,说明这个序列需要我们去更改
right++;
if(flag2 && !st.empty()){
if(st.top() == '('){
st.pop();
}else flag2 = false;
}else flag2 = false;
}
if(left == right){
if(flag2 == false){
ans += left*2;
}
left = 0;
right = 0;
flag2 = true;
while(!st.empty()) st.pop(); //手动清空栈
}
}
cout<<ans;
return 0;
}
/*
8
))((())(
4
(())
6
((()))
6
(()())
*/