HDU6299(2018多校第一场) Balanced Sequence(排序

题意
给你n个包含’(‘与’)’的字符串,可以将这些字符串任意排序,求所有排序中,子序列是正规括号序列的最大长度。
题解:
对于字符串排序,有两种解法

两个字符串的排序可以分成四种情况:
(1)str1左少右多 vs str2 左多右少
str2排在str1前面
(2)str1 左多右少 vs str2 左少右多
str1排在str2前面
(3)str1 左少右多 vs str2 左少右多
按左括号的数量排序
(4)其他情况按右括号的数量排

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N=1e6+100;
char s[N];
struct node
{
    int l,r;
    friend bool operator <(node a,node b)
    {
        if(a.l<=a.r&&b.l>b.r ) return 0;
        if(a.l>a.r&&b.l<=b.r) return 1;
        if(a.r>=a.l&&b.r>=b.l) return a.l>b.l;
        return a.r<b.r;
    }
}app[N];
int main()
{
    #ifdef local
        freopen("D://r.txt","r",stdin);
    #endif
    //ios::sync_with_stdio(false);
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int sum=0;
        for(int i=0;i<n;i++)
        {
            //cin>>str[i];
            scanf("%s",&s);
            int cnt1=0 ,cnt2 =0;
            for(int j=0;j<strlen(s);j++)
            {
                if(s[j]==')')
                {
                    if(cnt1!=0) cnt1--,sum+=2;
                    else cnt2++;
                }
                else cnt1++;
            }
            app[i].l=cnt1 ,app[i].r =cnt2 ;
        }
        sort(app,app+n);
        int cnt1=0,cnt2=0;
        for(int i=0;i<n;i++)
        {
            if(cnt1!=0)
            {
                int mi=min(cnt1 ,app[i].r);
                sum+=mi*2 ;
                cnt1-=mi;
                app[i].r-=mi;
            }
            cnt2+=app[i].r;
            cnt1+=app[i].l;
        }
        printf("%d\n",sum);
    }
    return 0;
}


首先我们对所有的字符串找到通过stack找到所有的串内正规括号子序列,之后剩下的串只有三种可能:
1. 只包含’(’
2. 先是一串’)’然后再是一串’(’
3. 只包含’)’
然后,按照第一类,第二类,第三类的顺序放置串。对于第二类内的排序,首先按照’(‘个数贡献正负排序,’)’个数小于’(‘个数则贡献为正,贡献是正的则排前面。然后正贡献的串,我们按照’)’个数从小到大排。负贡献的串,我们按照’(‘个数从大到小排。对于排序完的串,我们从前往后模拟记录一下即可。

#include <bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N=1e6+100;
char s[N];

struct node
{
    int l,r;
    friend bool operator <(node a,node b)
    {
        if(a.l-a.r>=0&&b.l-b.r>=0) return a.r<b.r;
        else if(a.l-a.r>=0) return 1;
        else if(b.l-b.r>=0) return 0;
        else return a.l>b.l;
    }
}app[N];
int main()
{
    #ifdef local
        freopen("D://r.txt","r",stdin);
    #endif
    //ios::sync_with_stdio(false);
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        int sum=0;
        for(int i=0;i<n;i++)
        {
            //cin>>str[i];
            scanf("%s",&s);
            int cnt1=0 ,cnt2 =0;
            for(int j=0;j<strlen(s);j++)
            {
                if(s[j]==')')
                {
                    if(cnt1!=0) cnt1--,sum+=2;
                    else cnt2++;
                }
                else cnt1++;
            }
            app[i].l=cnt1 ,app[i].r =cnt2 ;
        }
        sort(app,app+n);
        int cnt1=0,cnt2=0;
        for(int i=0;i<n;i++)
        {
            if(cnt1!=0)
            {
                int mi=min(cnt1 ,app[i].r);
                sum+=mi*2 ;
                cnt1-=mi;
                app[i].r-=mi;
            }
            cnt2+=app[i].r;
            cnt1+=app[i].l;
        }
        printf("%d\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ffgcc/article/details/81182279