[Acwing] 第54场周赛 4430.括号序列

前言

t a g : tag : tag: 括号序列 思维
传送门 :

题意 :
给定一个括号序列,询问有多少个合法位置,使得修改之后任然满足条件

条件 :

  • s s s中的()数量相同
  • 对于 s s s的任意前缀字符串,其中包含的(的数量均不少于)的数量

思路 :

考虑操作的只有两种 :

  • (改为) , R = L + 2 R=L+2 R=L+2
  • )改为(, L = R + 2 L=R+2 L=R+2

L , R 指 的 是 字 符 串 中 左 右 括 号 的 数 量 L,R指的是字符串中左右括号的数量 L,R

我们考虑第一种操作 :

我们认为(是向上的,)是向下的

因为我们需要满足第二个条件

所以当 y < 0 y<0 y<0的时候,必然是要做更改的
在这里插入图片描述

这时候我们发现我们更改前面任意一个)都可以使得其满足条件,因此总共有 r r r个位置

因为操作只有一次,所以我们只需要判断后面的位置是否合法即可

如果不合法,显然是不能再操作了的,所以 0 0 0

否则总操作次数就是 r r r

我们考虑第二种操作 :

因为字符串是可翻转的,因此我们翻转之后同第一种情况

code:

int n;
string s;

int work(){
	int cnt =0 ,r = 0 ;
	
	for(int i = 0;i<n;i++){
		if(s[i] == '(') cnt++;
		else{
			cnt -- ;
			r++;//前面的右括号 序列
			
			if(cnt < 0){//负数的时候开始统计答案
				cnt += 2;//改变之后 开始判断是否合法
				for(int j =i+1;j<n;j++){
					if(s[j] =='(') cnt++;
					else{
						cnt -- ;
						if(cnt <0) return 0;//如果后面不合法
					}
					
				}
				return r;
				
			}
		}
	}
	
	return 0;
}
void solve(){
	cin>>n>>s;
	
	int l = 0 ,r = 0 ;
	
	for(int i = 0 ;i<n; i++ )
	if(s[i] == '(') l++;
	else r ++;
	
	if(r == l+2) cout<<work()<<endl;
	else if(l == r+2){
		reverse(all(s));
		for(int i = 0;i<n;i++)
		s[i] = (s[i] == '(')?')':'(';
		
		cout<<work()<<endl;
		
	}else cout<<0<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值