天天看點

Codeforces Round #626 C. Unusual Competitions(括号比對)

傳送門

題意:

給一個長度為n的字元串,隻有 ′ ( ′ 和 ′ ) ′ '('和')' ′(′和′)′組成

我們可以選取任意一段長度為len的子串,把它随便排序,需要花費的時間為len秒,問最小需要多長時間,原字元串完全比對,不可能的話輸出-1

思路:

不可能的情況就是 ( 和 ) (和) (和)的數量不相等

為了盡可能短,那我們每次一遇到可能比對的(就是‘( ’和 ‘)’的個數相等的時候)就判斷一下

做法:

周遊一遍,記錄( 和 )的個數,當他們兩個數量相等時,判斷一下該段是否已經比對,若沒有比對需要花費時間排序,加上該段的長度即可

代碼:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <vector>
#include <math.h>
#include <map>
#include <queue>
#include <set>
#include <stack>
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
typedef long long ll;
using namespace std;
const int MAXN=1e6+50;
const int inf=0x3f3f3f3f;
const int M=5000*4;
char ch[MAXN];
int main()
{
    int n;
    cin>>n;
    cin>>(ch+1);
    int f=0;
    for(int i=1;i<=n;i++){
        if(ch[i]=='(')f++;
        if(ch[i]==')')f--;
    }
    if(f!=0){
        cout<<-1<<endl;
        return 0;
    }
    int ans=0,cnt=0,l,r;
    l=1;
    if(ch[1]=='(')f++;
    else f--;
    for(int i=2;i<=n;i++){
        if(ch[i]=='(')f++;
        else f--;
        if(f==0){//判斷l到i這一段是否已經比對
            stack<char>s;
            char chc;
        for(int j=l;j<=i;j++)
        {
        if(s.empty())
            s.push(ch[j]);
        else{
            chc=s.top();
            if(chc=='('&&ch[j]==')')
                s.pop();
            else
                s.push(ch[j]);
            }
        }
        if(!s.empty())ans+=(i-l+1);//說明沒有比對
        l=i+1;


        }
    }
    cout<<ans<<endl;
    return 0;
}
/*

*/