2020杭电多校第三场 1009 Parentheses Matching

题目

在这里插入图片描述

题目大题就是给定一个括号序列,其中仅包含()*,任务就是替换其中的*()或者空字符串,是的原字符串平衡且字典序最小。

一个不难想象到的是,最终的解法应该是在字符串的两侧不断替换括号,且两种括号的添加不能发生交叉。试想,如果替换出现了这种情况...)...(...。那么直接去掉这两个将会是长度更小的答案,所以这种情况是不会出现的。

为了解决问题,不妨将需要解决的问题分成两个步骤

  • 使括号数量平衡
  • 使括号配对平衡

首先拿到序列先在一侧添加括号,使得左右括号一样多。达成这一点很简单,扫描一遍整个数组即可。
在扫描的过程中,还能完成另一项任务:判定是否有解!!准确些说,就是对于一个位置前面的)多于(*的总和,或者一个位置后面的多于*的总和。这个在一次正向遍历中就能解决。
判断完结果后,把缺少的括号补充在一侧即可

scanf("%s",str);
n = strlen(str);
cntL = cntR = 0;
L = R = 0;
for(int i = 0;i < n && R >= 0;i++){
   
   
	if(str[i] == '('){
   
   
		L++;
		cntL++;
	}else{
   
   
		(--L) < 0 && (L = 0);
	}
	
	if(str[i] == ')'){
   
   
		R--;
		cntR++;
	}else{
   
   
		R++;
	}
}

if(L > 0 || R < 0){
   
   
	printf("No solution!\n");
	continue;
}

for(int i = 0;i < n && cntR - cntL > 0;i++){
   
   
	if(str[i] == '*'){
   
   
		str[i] = '(';
		cntL++;
	}
}

for(int i = n - 1;i >= 0 && cntL - cntR > 0;i--){
   
   
	if(str[i] == '*'){
   
   
		str[i] = ')';
		cntR++;
	}
}

经过上面的操作,两种括号的数量平衡了,可以说明的是现在待处理的问题串变成了这个亚子:....).)).))...(((.((....
省略掉的是*和已经配好对的括号。且这里不难看出,两种未配对的括号各处一边,数量相等。 且经过上面的筛选,解是一定存在的。
下面的任务就是找到这些括号的数量了,有两种思路,一种是二分试出来,另一种是贪心的思想遍历一下找出来。

二分

对填充一种括号的数量进行二分,下限是0,上限是剩余*数量的一半(因为括号要成对添加)。
每次枚举出数量放进去试一试,不合法就是少了,合法就是正好或者多了。

二分代码:

L = 0;
R = (n - cntL - cntR) >> 1;
int M,cnt;
while(L < R){
   
   
	M = (L + R) >> 1;
	strcpy(temp,str);
	
	for(int i = n - 1,suf = M;i >= 0,suf > 0;i--){
   
   
		if(temp[i] == '*'){
   
   
			temp[i] 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值