bzoj 4936: [Ceoi2016]match

来源:互联网 发布:大阪大型超市 知乎 编辑:程序博客网 时间:2024/06/05 19:05

Description

给你一个由小写字母组成的字符串s,要你构造一个字典序最小的(认为左括号的字典序比右括号小)合法的括号
序列与这个字符串匹配,字符串和括号序列匹配定义为:首先长度必须相等,其次对于一对匹配的左括号和右括号
i,j,必须有s[i]==s[j]
无解输出-1
Input

一行一个字符串s

2<=n<=100000
Output

一行一个括号序列或者-1

Sample Input

abbaaa
Sample Output

(()())

题解

很好的一道题啊。。
一开始脑残了。。
写了个这个:

#include<cstdio>#include<cstring>const int N=100005;char ss[N];int len;int lalal[30];//每个字母出现了多少次 int now[30];int main(){    scanf("%s",ss);    len=strlen(ss);    for (int u=0;u<len;u++)  lalal[ss[u]-'a']++;    for (int u=0;u<26;u++)        if (lalal[u]%2!=0)        {            printf("-1");            return 0;        }    for (int u=0;u<len;u++)    {        now[ss[u]-'a']++;        if (now[ss[u]-'a']*2>lalal[ss[u]-'a'])            printf(")");        else printf("(");    }    return 0;}

感觉就是智障了。。
然后冥思苦想了半小时没想出来,就去%题解了
感觉写得非常好了,我就不做过多无用的解释了

AC CODE:

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<stack>#include<map>using namespace std;typedef long long LL;const LL MOD=10037;const LL MOD1=1000000007;const int N=100005;char ss[N];int len;LL p[N];LL lalal[N];LL now;stack<int> S;map<LL,int>R[30];int L[N];int ans[N];void solve (int l,int r){    if (l>r) return ;    ans[l]=1;    int x=ss[l]-'a'+1,pos=R[x][lalal[l-1]];    while (ans[pos]!=0) pos=L[pos];    R[x][lalal[l-1]]=L[pos];    ans[pos]=2;    solve(pos+1,r);solve(l+1,pos-1);//这个顺序十分重要 }int main(){    scanf("%s",ss+1);len=strlen(ss+1);    p[0]=1;for (int u=1;u<=len;u++) p[u]=p[u-1]*MOD%MOD1;    lalal[0]=0;now=0;    for (int u=1;u<=len;u++)    {        LL x=ss[u]-'a'+1;        if (S.empty()||ss[S.top()]!=ss[u])        {            S.push(u);            now=(now+x*p[S.size()]%MOD1)%MOD1;        }        else now=((now-x*p[S.size()]%MOD1)%MOD1+MOD1)%MOD1,S.pop();        lalal[u]=now;    }    if (!S.empty()) {printf("-1");return 0;}    for (int u=1;u<=len;u++)    {        int x=ss[u]-'a'+1;        L[u]=R[x][lalal[u]];        R[x][lalal[u]]=u;    }    solve(1,len);    for (int u=1;u<=len;u++)    {        if (ans[u]==1) printf("(");        else printf(")");    }    return 0;}