Bad Sequence
题目链接:http://codeforces.com/contest/1214/problem/C
题意: 给出字符串长度,和一段只含左右括号的字符,并定义该字符序列是好的条件为括号匹配或者只通过移一个括号,能使其完全匹配,如果满足上述条件,则输出Yes,否则输出No。
思路: 首先对n进行奇偶判断,奇数直接输出No,因为左括号数不等于右括号数,如果为偶数则用栈去模拟括号是否匹配(遇到左括号入栈,遇到右括号且栈不为空出栈),同时记录左括号数目和右括号数目,如果左括号数目不等于右括号数目,直接输出No,如果相等,再判断栈里的剩余左括号数目,如果其数目小于等于1,则输出Yes,否则输出No。详情看代码和注释。
#include <bits/stdc++.h>
const int maxn=1e6+5;
using namespace std;
#define LL long long
char a[maxn];
int main(){
ios::sync_with_stdio(0);
int n;
cin>>n;
cin>>a;
if(n%2==1){
cout<<"No"<<endl;
return 0;
}
stack<char> qt;
int num=0,num1=0;
for(int i=0;i<n;i++){
if(a[i]=='(')
qt.push(a[i]);
else if(!qt.empty()&&a[i]==')')
qt.pop();
if(a[i]=='(')
num++;
else
num1++;
}
if(qt.empty()&&num==num1)
cout<<"Yes"<<endl;
else{
if(qt.size()>1||num!=num1)
cout<<"No"<<endl;
else
cout<<"Yes"<<endl;
}
return 0;
}
做法2:
考虑判断一个括号序列是否合法的方法,就是把(当成1,)当成-1,前缀和之后看是否出现过小于0的前缀和,再判断最后的和是否为0.
这道题同理,我们只需要判断是否出现过小于-1的前缀和,最后判断和是否为0即可。
#include<stdio.h>
const int maxn = 2e5+10;
char str[maxn];
int main()
{
int n;
scanf("%d",&n);
scanf("%s",str+1);
int sum = 0;
int flag=0;
for(int i=1;i<=n;i++)
{
if(str[i]=='(') sum++;
else sum--;
if(sum<-1) flag=1;
}
if(sum!=0) flag=1;
if(flag==0) puts("YES");
else puts("NO");
return 0;
}