Codeforces 1153 C Serval and Parenthesis Sequence

题意:
给一个字符串 只包含 ‘(’ 、 ‘)’ 、和 ’ ?’ 要求改变 ‘?’ 为 ‘(’ 或 ‘)’ 使最终的字符串满足:从第一位开始到任意一位(非最后一位)的字符串不出现形如 ‘( )’的情况 如果没有情况满足 输出 ’ : ) ’

思路:
贪心,当n为奇数或s的首字符为)或s的末尾字符为(时,必定不满足题意;
也就是说s的首个字符必定是(且末尾字符必定是),那么对于1<=i<n的所有i,必须满足[1,i]内的(的个数大于)的个数。

考虑用一个数先记录下当前字符串中”(‘的个数,然后用n/2-当前的得到还需要转化的。然后在进行遍历转化。

在转化后通过遍历字符串 统计 l 和 r 括号的数目 必须满足 在最后一位之前必须有 l > r 且不可以相等 。来检验是否合法。

AC代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define max 2000

int n;

bool check(string ss,int & l,int & r) //检验最终的字符串是否合法
{
	bool is_true = true;
	for (int i = 0; i < n; i++)
	{
		if (ss[i] == '(')
			++l;
		if (ss[i] == ')')
			++r;
		//因为"(" 个数与")"相同,且最后一个为")",那么在最后一个之前,"("个数必须大于")"
		if (l <= r && i != n - 1) 
		{
			is_true = false;
			break;
		}
	}
	return is_true;
}

void show(string ss, bool is_true,int l,int r)
{
	if (is_true)
	{
		if (l == r)
			cout << ss << endl;
		else
			cout << ":(" << endl;
	}
	else
		cout << ":(" << endl;
}

int main()
{
	string ss;
	while (cin >>n>> ss)
	{
		if((n&1)|| ss[0] == ')' || ss[n - 1] == '(')
			cout << ":(" << endl;
		else
		{
			int count1 = 0;
			ss[0] = '(', ss[n - 1] = ')';
			for (int i = 0; i < n; i++)
			{
				if (ss[i] == '(')
					++count1;     //现在字符串中已经有的
			}
			//因为一半是“(”,s所以现在count1表示还需要转化为“(”的个数
			count1 = n / 2 - count1; 

			for (int i = 0; i < n; i++)
			{
				if (ss[i] == '?' && count1)
				{
					ss[i] = '(';
					--count1;
				}
				else if (ss[i] == '?')
					ss[i] = ')';
			}
			int l = 0, r = 0;
			bool is_true = check(ss,l,r);
			show(ss, is_true,l,r);
		}
	}
	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落春只在无意间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值