首页 > 其他 > 详细

51nod 1791合法括号子段

时间:2018-04-03 23:29:30      阅读:237      评论:0      收藏:0      [点我收藏+]

有一个括号序列,现在要计算一下它有多少非空子段是合法括号序列。

合法括号序列的定义是:

1.空序列是合法括号序列。

2.如果S是合法括号序列,那么(S)是合法括号序列。
3.如果A和B都是合法括号序列,那么AB是合法括号序列。

Input
多组测试数据。
第一行有一个整数T(1<=T<=1100000),表示测试数据的数量。
接下来T行,每一行都有一个括号序列,是一个由‘(‘和‘)‘组成的非空串。
所有输入的括号序列的总长度不超过1100000。
Output
输出T行,每一行对应一个测试数据的答案。
Input示例
5
(
()
()()
(()
(())
Output示例
0
1
3
1
2

()是一个合法括号序列,()()是两个合法括号序列。

主要要解决两个合法括号序列组合成新的合法括号序列这个问题。pos[i] 表示第i个右括号与之对应的左括号的位置。ans[i] 表示 在第i个位置一共有多少个。

然后把ans求和就行了。

#include <iostream>
#include <stdio.h>
#include <stack>
#include <string.h>
#define ll long long
using namespace std;
const int N = 1100010;
int t, len;
char str[N];
ll pos[N], ans[N];
int main() {
	scanf("%d",&t);
	while(t--) {
		scanf("%s",str+1);
		len = strlen(str+1);
		for(int i = 0; i <= len; i ++) {
			pos[i] = -1;
			ans[i] = 0;
		}
		stack<int> st;
		for(int i = 1; i <= len; i ++) {
			if(str[i] == ‘(‘) st.push(i);
			else {
				if(!st.empty()) {
					pos[i] = st.top();
					st.pop();
				}
			}
		}
		ll toc = 0;
		for(int i = 1; i <= len; i ++) {
			if(pos[i] != -1) {
				ans[i] = ans[pos[i]-1]+1;
				toc += ans[i];
			}
		}
		cout << toc << endl;
	}
	return 0;
}

  

51nod 1791合法括号子段

原文:https://www.cnblogs.com/xingkongyihao/p/8711321.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!