传送门:51nod 1478
思路:
一般与括号匹配有关的问题基本套路就是先直接来一遍括号匹配,然后再处理一下。
一开始我想一遍匹配一遍确定答案,但是这样有个问题:无法确定长度值什么时候归零。换句话说,对于当前符号,无论是 '(' 还是 ')' 都无法直接判断连续的括号匹配是否结束了。
于是我就换了种思路,用 vis 数组记录括号的匹配情况。在进行括号匹配的同时把可以匹配的左右括号的 vis值置为 1 。然后再扫描一遍 vis 中连续的 1 最长是多少,如果存在多个记录个数即可。
代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<stack>
using namespace std;
int vis[1000010];
int main()
{
int i,len,sum,num,ans;
char s[1000010];
stack<int> st; //栈记录的是左括号的位置
while(~scanf("%s",s))
{
while(!st.empty()) st.pop();
len=strlen(s);
memset(vis,0,sizeof(vis)); //清零
for(i=0;i<len;i++)
{ //括号匹配
if(s[i]=='(') st.push(i); //如果是左括号则记录位置
//如果是右括号并且栈非空则匹配
else if(!st.empty())
{
int top=st.top();
st.pop();
vis[top]=1; //将匹配的括号置 1
vis[i]=1;
}
}
sum=ans=0;
for(i=0;i<=len;i++)
{ //扫描一遍 vis数组
if(vis[i]) sum++; //如果是 1,长度 +1
else
{ //如果是 0,更新结果
if(sum>ans)
{ //更新最大值
ans=sum;
num=1;
}
else if(sum==ans) num++; //更新次数
sum=0;
}
}
if(ans==0) printf("0 1\n");
else printf("%d %d\n",ans,num);
}
return 0;
}