codeforces 贪心 Recover an RBS

 

题目概述:

        给定一个RBS(一定是合法的),它的括号表达式是否是唯一的。 

贪心法一:

        括号匹配问题:从左到右遍历,( 的数目应当不小于 ) 的数目,最后两者相等。 

        我们从左到右遍历,用 dep 表示 ( 的个数,没遇到一个 ( , dep 要加 1。我们用 now 表示 ? 的个数。

        当我们遇到一个 ) 时,dep 要减 1, 如果dep 要小于 0 了,说明我们需要 之前的 ? 来当做 ( 用,因为这是个合法的 RBS, 所以我们的 ‘?’ 肯定是够用的,所以 now --, dep++, 这样一来 dep 一直都不会是一个负数。此外,当dep 为 0 且 ?的数目 为 1时,这个?必须转化为左括号。遍历结束后,还有 dep 个左括号,以及 now 个没有用过的 ? 号,如果两者相等,则所有的 ? 应该都是右括号,结果唯一。

        下面看这个示例:? (?) ()? ) 

        首先 now = 1, dep = 0, 这个必须为左括号,所以 now = 0, dep = 1;

        遇到左括号, now = 0, dep = 2;

        遇到?, now = 1, dep = 2;

        遇到右括号, now = 1, dep = 1;

        now = 1, dep = 2;

        now = 1, dep = 1;

        now = 2, dep = 1;

        now = 2, dep = 0;

        最后 now 不等于 dep, 则表示不可以。

贪心法二:

        首先尽可能左边的? 填 左括号, 最后的一些 ? 填右括号。这是肯定能够成功地一组填法。

        然后,我们交换  所填的最右边的 ( 所填入的最左边的 ) , 这样是我们构造出的最可能成功的另一种匹配方案,如果这种方案也可以成功地话,那么解法一定大于等于 2,否则只有 1.

#include<iostream>
using namespace std;
#include<vector>
#include<algorithm>
#include <numeric>
#include <string>
int main() {
	int T, now, dep, i, len;
	cin >> T;
	while (T--)
	{
		string s;
		cin >> s;
		len = s.size();
		now = 0;
		dep = 0;
		for (i = 0; i < len; i++)
		{
			if (s[i] == '(')
				dep++;
			else if (s[i] == ')')
			{
				dep--;
				if (dep < 0)
				{
					dep++;
					now--;
				}
			}
			else
				now++;
			if (dep == 0 && now == 1)
			{
				dep++;
				now--;
			}
		}
		if (dep == now)
			cout << "YES\n";
		else
			cout << "NO\n";
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值