括号匹配 | ||
Accepted : 26 | Submit : 210 | |
Time Limit : 10000 MS | Memory Limit : 65536 KB |
题目描述有一串括号(只包含"(", ")", "[", "]", "{", "}"), 保证这一括号串是匹配的, 长度小于100000, 有m个询问, 每个询问为一个整数x;对于每一个询问, 要求输出一行四个整数y, a, b, c; 表示第x个括号是跟第y个配对的, x和y之间有a对小括号, b对中括号, c对大括号。 输入约200个样例, 每个样例第一行为一个只包含括号的长度小于100000的字符串, 第二行一个小于100000的整数m, 接下来m行每行一个整数x,x不大于括号字符串的长度, x > 0; 输出每个询问输出一行四个整数y, a, b, c,用空格隔开。每个样例之后输出一个空行 样例输入(){}[] 3 1 3 5 [([{()[]}])][()] 5 1 2 5 13 14 样例输出2 0 0 0 4 0 0 0 6 0 0 0 12 2 2 1 11 1 2 1 6 0 0 0 16 1 0 0 15 0 0 0 |
<pre name="code" class="cpp">/*
H.括号匹配
链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1232
题意:如题。
分析:用栈解决“左右括号的匹配问题”,用队列解决“包含多少对括号的问题”。
(下面用了3个栈,不过应该一个栈就ok了)
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 100005;
int q[3][maxn], s[3][maxn];
int qt[3], st[3];
int mat[256];
char str[maxn];
int ans[maxn];
void init()
{
mat['('] = 0;
mat['['] = 1;
mat['{'] = 2;
mat[')'] = 3;
mat[']'] = 4;
mat['}'] = 5;
for (int i = 0; i<3; i++)
qt[i] = st[i] = 0;
}
int main()
{
//freopen("input.txt","r",stdin);
while (~scanf("%s", str + 1))
{
init();
int len = strlen(str + 1);
for (int i = 1; i <= len; i++)
{
int n = mat[str[i]];
if (n < 3)//如果是左括号
{
s[n][st[n]++] = i;//进栈
q[n][qt[n]++] = i;//进队
}
else//如果是右括号
{
int L = s[n - 3][--st[n - 3]];//取栈顶元素并出栈
ans[i] = L;
ans[L] = i;
}
}
/*------------------------------------------*/
int m, x, a[3];
scanf("%d", &m);
for (int i = 0; i<m; i++)
{
scanf("%d", &x);
int n = mat[str[x]];
int low = min(x, ans[x]);
int up = max(x, ans[x]);
/*查找low和up之间有多少对括号*/
for (int j = 0; j<3; j++)
{
int L = upper_bound(q[j], q[j] + qt[j], low) - q[j];
int R = lower_bound(q[j], q[j] + qt[j], up) - q[j];
a[j] = R - L;
}
printf("%d %d %d %d\n", ans[x], a[0], a[1], a[2]);
}
printf("\n");
}
return 0;
}