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;
}
原文地址:https://www.cnblogs.com/eason9906/p/11754765.html