问题 A: 括号匹配2019
时间限制: 1 Sec 内存限制: 128 MB
提交: 528 解决: 158
[提交] [状态] [命题人:admin]
题目描述
w222222s发现了一个由'('和')'组成的环,他想知道如果将环从某处断开,得到的序列有没有可能让括号能够匹配。比如环"))(("可以拆成"))((" "())(" "(())" ")(()"四种,其中"(())"的括号就能够匹配,另外三种则不能。
请你帮他设计一个程序,可以知道,由括号组成的环能不能得到一个可以匹配的序列。
输入
输入有多行。
每行都有一个由'('和')'组成的字符串,表示由'('和')'组成的环。
所有字符串的长度的和不超过100000
输出
对于每一行所表示的环,判断能不能得到可以括号匹配的序列,如果有输出"YES",否则输出"NO"。
样例输入
复制样例数据
))((
样例输出
YES
这题可以直接判断是否左括号个数等于右括号个数
具体证明呢,可以这样想
先把能匹配的匹配了,不能匹配的就留在原序列,就像玩一个消消乐
例如))(())(,这样先把能匹配的匹配掉(因为不影响),就变成了
))(,然后我们考虑一下,剩下的一定是先右括号(如果有)再左括号(如果有)
也就是说剩下的那几种情况就是
空,))),(((,))(
就这四种,显然对于第四种情况,我们可以把前面几个),挪到整个串的后面去和那些(匹配
那么,显然就是只有)(个数相等的时候才可以了
所以这题可以这么A,这也是我的做法
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+7;
char s[maxn],stk[maxn];
int top;
bool isok(){
if(top&1)return 0;
int cnt = 0;
for(int i=0;i<top;i++)if(stk[i] == '(')cnt++;
return (cnt<<1) == top;
}
int main(){
while(~scanf("%s",s)){
top = 0;
for(int i=0;s[i];i++){
if(s[i] == '(')
stk[top++] = '(';
else if(top && stk[top-1] == '(')
top--;
else
stk[top++] = ')';
}
if(top == 0 || isok())puts("YES");
else puts("NO");
}
return 0;
}
但是,综合一下
中间匹配掉的一定是)(相等,所以可以直接判断)(是否相等就可以了