CF-div2-626-C.Unusual Competitions

岁酱吖の 提交于 2020-03-09 21:49:16

法一:

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
(()())
*/
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!