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
(()())
*/
posted @ 2020-03-09 19:44  fishers  阅读(276)  评论(0编辑  收藏  举报