您的位置:首页 > 产品设计 > UI/UE

CF_5C_LongestRegularBracketSequence

2016-03-30 20:26 555 查看
C. Longest Regular Bracket Sequence

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

This is yet another problem dealing with regular bracket sequences.

We should remind you that a bracket sequence is called regular, if by inserting «+» and «1»
into it we can get a correct mathematical expression. For example, sequences «(())()», «()»
and «(()(()))» are regular, while «)(», «(()»
and «(()))(» are not.

You are given a string of «(» and «)» characters. You are to
find its longest substring that is a regular bracket sequence. You are to find the number of such substrings as well.

Input

The first line of the input file contains a non-empty string, consisting of «(» and «)»
characters. Its length does not exceed 106.

Output

Print the length of the longest substring that is a regular bracket sequence, and the number of such substrings. If there are no such substrings, write the only line containing "0
1".

Examples

input
)((())))(()())


output
6 2


input
))(


output
0 1


题目意思求给出的括号串中最长的合法括号序列

这题目最开始想的用1 -1前缀和解决 但是发现很多情况并不能处理

这里可以这样想 首先)肯定是匹配的最近的没有匹配的(

不然一定出现没有匹配的或者交替匹配的

于是可以把(入栈 遇到)则出栈一个

而 目前两个()之间的括号序列一定是匹配的

于是只需要把所有的(的位置入栈 出栈时计算下即可知道当前括号序列的长度

但是 这里注意到一点 一个合法的括号序列并不一定是(…… 序列 ……)这样的形式

也可能是(……)(……)这样的形式

于是 用一个数组管理到目前位置的合法序列长度 于是每次得到匹配的括号更新这个值即可

有点dp思想

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
using namespace std;

const int M=1e6+5;
char s[M];
int n[M];//保存到当前位置最长的合法序列长度

stack<int> st;

int main()
{
scanf("%s",s+1);
int l=strlen(s+1);
int ml=0,mn=1;
//最大子串长度,子串个数
//    int su=0;   //前缀和
for(int i=1;i<=l;i++)
{
if(st.empty()&&s[i]==')')
continue;
if(s[i]==')')
{
n[i]=i-st.top()+1+n[st.top()-1];
st.pop();
if(n[i]==ml)
mn++;
if(n[i]>ml)
{
ml=n[i];
mn=1;
}
}
else
st.push(i);
//cout<<"i "<<i<<" nl "<<n[i]<<endl;
}
printf("%d %d\n",ml,mn);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: