码迷,mamicode.com
首页 > 其他好文 > 详细

51nod 1791合法括号子段

时间:2018-04-03 23:45:51      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:pac   push   char   gray   toc   clu   现在   turn   while   

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

合法括号序列的定义是:

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合法括号子段

标签:pac   push   char   gray   toc   clu   现在   turn   while   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!