鏈接: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;
}