CF #551 (Div. 2) C. Serval and Parenthesis Sequence(貪心,字符串)

鏈接:CF #551 (Div. 2) C. Serval and Parenthesis Sequence

題意:

給定由"(",")","?“組成的字符串,問是否能將其中”?“的全部換成”(",")"使得字符串的任意的前 i ( i<L)個字符不是正確的括號串,而整體是一個正確的括號串(即每個括號都有所匹配)。

輸入:

第一行包含是一個整數 |s| (1 ≤ |s| ≤ 3⋅105),表示字符串的長度

第二含包含一個只含 “(”, “)” 和 "?"的字符串

輸出:

一行字符串表示答案;

如有多個答案,輸出其中一個即可;

如果沒有答案,輸出 “: (” (不含引號)。

樣例

輸入:

6
(???

輸出:

(()())

輸入:

10
(???(???(?

輸出:

: (



分析:

  • 首先考慮 什麼樣的字符串是符合題目要求的字符串

將 “(” 替換爲爲+1,")"替換爲-1,從頭到尾逐個累加,在到末尾之前,必須滿足 sum >= 0(若 sum<0,說明有多餘的 “)” 再也無法匹配;若sum==0,說明前 i 個字符有正確括號串),而到末尾後,需滿足sum=0。

  • 然後就是用貪心的方法填充"?"

最後的理想狀態( 如"(((())))" )是 左括號數量x == 右括號數量y == N/2,所以先通過遍歷字符串中原有的 “(” , “)”,算出一共要填充多少個左、右括號。

填充時優先填充左括號"(",左括號"(“填完以後再填右括號”)",這樣貪心就可以達到理想狀態。



以下代碼:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=3e5+10;
int main()
{
	int N;
	char s[maxn];
	scanf("%d %s",&N,s);
	if(N%2==1||s[0]==')'||s[N-1]=='(')       //初步判斷
	{
		printf(":(");
		return 0;
	}
	int x=N/2,y=N/2;
	for(int i=0;i<N;i++)       //確定x,y
	{
		if(s[i]=='(')
			x--;
		if(s[i]==')')
			y++;		
	}
	for(int i=0;i<N;i++)       //填充括號
	{
		if(s[i]=='?')
		{
			if(x>0)
			{
				s[i]='(';
				x--;
			}
			else
				s[i]=')';
		}
	}
	int sum=0;
	for(int i=0;i<N;i++)        //驗證其正確性
	{
		if(s[i]=='(')
			sum++;
		else
			sum--;
		if(i!=N-1&&sum<=0)      //若過程中sum<=0
		{
			printf(":(");
			return 0;
		}
	}
	if(sum==0)                  //最終sum==0
		printf("%s",s);
	else
		printf(":(");
    return 0; 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章