栈和队列_9
一、HZOJ-265
括号画家
Candela是一名漫画家,她有一个奇特的爱好,就是在纸上画括号。这一天,刚刚起床的 Candela画了一排括号序列,其中包含小括号 ()、中括号 [] 和大括号 {},总长度为 N。这排随意绘制的括号序列显得杂乱无章,于是 Candela定义了什么样的括号序列是美观的:
- 空的括号序列是美观的;
- 若括号序列
A
是美观的,则括号序列(A)、[A]、{A}
也是美观的; - 若括号序列
A、B
都是美观的,则括号序列AB
也是美观的;
输入:
1个长度为 N的括号序列。(5≤N≤10000)
输出:
一个整数,表示最长的美观的连续子序列的长度。
样例输入:[[[[]]{}]]
样例输出:
10
二、题解
1.引库
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <stack>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <vector>
using namespace std;
2.代码
1.用栈处理得到每对括号的匹配关系
2.根据匹配关系获得最长的长度
#define MAX_N 10000
char str[MAX_N+5];
int match[MAX_N+5]={0};//0是不合法的匹配
stack<int> s;
int main(){
cin>>(str+1);
for(int i=1;str[i];i++){
switch(str[i]){
case '(':
case '[':
case '{':{
s.push(i);
break;
}
case ')':
if (!s.empty() && str[s.top()] == '(') {
match[s.top()] = i;
match[i] = s.top();//这个记录其实没有用到
s.pop();
} else {
s.push(i);
}
break;
case ']':{
if (!s.empty() && str[s.top()] == '[') {
match[s.top()] = i;
match[i] = s.top();
s.pop();
} else {
s.push(i);
}
break;
}
case '}':{
if (!s.empty() && str[s.top()] == '{') {
match[s.top()] = i;
match[i] = s.top();
s.pop();
} else {
s.push(i);
}
break;
}
}
}
/*for(int i=1;str[i];i++){//输出下 合法位置序列
printf("match[%d]=%d\n",i,match[i]);
}*/
int ans=0,temp_ans=0,i=1;
while(str[i]){
if(match[i]){
temp_ans+=(match[i]-i+1);//+=是因为可能前面的括号已经闭合,后面的闭合括号需要叠加计算长度
i=match[i]+1;
}else{
i++;
temp_ans=0;
}
if(temp_ans>ans) ans=temp_ans;
}
cout<<ans<<endl;
return 0;
}