C. Serval and Parenthesis Sequence(贪心)
题意是给你一个s,包含?(),然后可以把?变成(或),然后问你是否存在一个方案可以使得s的所有严格前缀都是不合法的,然后s是合法的。
可以这样想,假如有a个括号,其中有b个需要变(,c个需要变),我们就直接对s进行操作,把前b个变(,后c个变),这样做的原因是因为如果有解的话,肯定是对每个位置1到n-1的前缀而言(个数>)个数的,这样的话就能使得每一个前缀里(个数尽可能大于)个数,所以对?优先变(肯定是最优的,完了之后再对s进行括号匹配即可。
#include<bits/stdc++.h>
using namespace std;
#define fuck(x) cout<<#x<<" "<<x<<endl;
const int maxn=3e5+10;
stack<char>sta;
char s[maxn];
int main()
{
int n,num1=0,num0=0;
bool flag=1;
scanf("%d",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++)
if(s[i]=='(')
num1++;
else
if(s[i]==')')
num0++;
for(int i=1;i<=n;i++)
if(s[i]=='?')
{
if(num1<n/2)
s[i]='(',num1++;
else
if(num0<n/2)
s[i]=')',num0++;
else
flag=0;
}
if(!flag)
{
cout<<":("<<endl;
return 0;
}
// cout<<s+1<<endl;
// fuck(flag);
for(int i=1;i<=n;i++)
{
if(sta.empty())
{
if(s[i]=='(')
sta.push(s[i]);
else
flag=0;
}
else
{
if(s[i]=='(')
sta.push(s[i]);
else
sta.pop();
}
if(i!=n&&sta.size()==0)
flag=0;
}
if(!flag||sta.size())
cout<<":("<<endl;
else
cout<<s+1<<endl;
return 0;
}