2 条题解
-
2
可以将这个字符串从左往右写,一旦遇到匹配上的括号,就把这对括号擦掉,就像“消消乐”一样。 以[([])[]]为例,从左往右写,写到[([],产生了匹配,所以把[]擦掉,纸上的字符串变成了[(,接着写,下一个字符是),字符串编程[(),产生了匹配。擦掉(),纸上只剩下了一个[。接下来,往后写一个字符,变成[[,没有产生匹配。再写一个变为[[],擦掉[],纸上又只剩下一个[。接下来写],产生了匹配,擦掉[]之后纸上什么也不剩了。因此所给字符串是合法的。
如果处理字符串的所有字符,发现纸上还剩有括号,那么就说明有些括号没有被匹配到,说明是非法的括号序列,比如([)(])根据上面的做法就可以知道是非法的。
我们可以把写一个字符视为入栈,把括号匹配视为栈顶元素出栈,从而使用栈的两个操作来完成模拟的过程。
#include<bits/stdc++.h> using namespace std; const int N=10005; string s; char sta[N]; int l,top; int main(){ int T;cin>>T; while (T--){ cin>>s; top=0; l=s.size(); for (int i=0;i<l;++i){ if (s[i]==')' && sta[top]=='(') --top; else if (s[i]==']' && sta[top]=='[') --top; else sta[++top]=s[i]; } if (top) cout<<"No\n"; else cout<<"Yes\n"; } }
-
0
括号序列匹配是栈的经典题了。题解里有用手搓栈做的,那我就提供一个用STL栈做的吧。
原理可以看其他的题解,我这里就提供一个做法。
我们从左到右依次扫描括号序列:
- 如果它是
(
或[
,我们就把它加入栈中。 - 如果它是
)
或]
,我们就判断:- 如果栈顶是当前扫描到的右括号对应的左括号,我们就将栈顶的左括号弹出。
- 否则说明当前扫描到的右括号无法正确匹配前面的左括号,我们就退出循环并输出
No
。
循环结束后如果没有发现非法的括号,我们就输出
Yes
。AC code:
#include<bits/stdc++.h> #define ll long long using namespace std; ll n; int main(){ scanf("%lld",&n); for(ll i=1;i<=n;i++){ string s; stack<char> sta; bool flag=1; cin>>s; for(ll i=0;i<s.length();i++){ if(s[i]=='('||s[i]=='[') sta.push(s[i]); else if(s[i]==')') if(!sta.empty()&&sta.top()=='(') // 要记得加上!sta.empty(),否则会RE sta.pop(); else{ flag=0; break; } else if(!sta.empty()&&sta.top()=='[') // 要记得加上!sta.empty(),否则会RE sta.pop(); else{ flag=0; break; } } if(flag) puts("Yes"); else puts("No"); } return 0; }
- 如果它是
- 1
信息
- ID
- 535
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- (无)
- 递交数
- 194
- 已通过
- 76
- 上传者