【CF#818】【栈的括号匹配】

从1向2*n枚举字符串的元素,用栈保存遇到的左括号(还没和右括号匹配的),遇到右括号的时候,

如果栈中有元素(左括号),那么它是能和 枚举到的右括号匹配的,

那么就弹出这个左括号。

如果栈中没有元素(没有还没被匹配的左括号),那么这个右括号就是孤身一人的,

会影响它所在子括号序列的合法性。

我用 f[ i ] 来标记所有孤身一人的,可怜的右括号。( f [ i ] = 1 )

这些光棍会把整个序列分为好几段,

光棍1前面的序列是合法的,

光棍1到光棍2之间的序列是合法的

光棍2到光棍3之间的序列是合法的

 

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;

char s[2*N];
int f[2*N];
int mat[2*N];
int st[2*N];
int stk[2*N],top;

int main()
{
	int t;
    scanf("%d",&t);
	while(t--)
	{
		
		int n;
		scanf("%d",&n);
		for(int i=1;i<=2*n;i++) 
		{
		  f[i]=0;
		  mat[i]=0;
		  st[i]=false;
		}
	    scanf("%s",s+1);
		
	    top=0;
		int v;
		for(int i=1;i<=2*n;i++)
		{
			if(s[i]=='(')
			{
				stk[++top]=i;
			}
			else if(s[i]==')')
			{
				if(top>=1)
				{
					int tt=stk[top--];
				
					mat[i]=tt;
				}
				else if(top==0)
				{
					f[i]=1;
				}
			}
		}

	
	int sum=0;
	//匹配起来 
	int pz=-1;
	for(int i=1;i<=2*n;i++)
	{
		if(s[i]=='(')
		{
		
		   if(i==1||s[i-1]==')')
		   {
		   if(pz==-1)
		   {
			   pz=i;
			   if(!st[pz])
			   {
			   st[pz]=pz;
			   sum++;
		       }
		   }
		   else
		   {
		   	st[i]=pz;
		   }
	     }
	    }
	    else if(s[i]==')')
	    {
	    	if(f[i])
	    	{
	    		pz=-1;
			}
		}
	}

		for(int i=1;i<=2*n;i++)
		{
			if(s[i]==')')
			{
				//x和i 
				int x=mat[i];
			    if(!st[x]&&!st[i])
			    {
			    	sum++;
			    	st[x]=x;
			    	st[i]=x;
				}
				else if(st[x]&&!st[i])
				{
					st[i]=st[x];
				}
				else if(!st[x]&&st[i])
				{
					st[x]=st[i];
				}
			}
		}
		
	
		
		
	printf("%d\n",sum);
	}
	
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值