题解

31 条题解

  • 7
    @ 2017-10-08 08:43:50

    抛砖引玉,分享两种做法。
    第一种,栈,因为我很菜鸡所以开了不少大数组。
    具体思路:遇到左括号就进栈q(保存位置,f保存相对应的右括号)。遇到右括号判断栈顶元素是否与之对应,对应则出栈,将括号内范围标1(f1数组);不对应则栈清空,这一块都不行了。最后循环找出最长的括号串输出。
    菜鸡我一开始是保存的起始点,后来发现有并列情况啊不好处理。
    代码如下:

    #include<cstdio>
    #include<cstring>
    int q[5000005],top;
    bool f1[5000005];
    char c[5000005],f[5000005];
    int main()
    {
        int i,j,maxn=0,s=0,x=0,mx,l;
        scanf("%s",c);
        l=strlen(c);
        for (i=0;i<l;i++)
        {
            if (c[i]=='(') {q[++top]=i; f[top]=')';}
            if (c[i]=='[') {q[++top]=i; f[top]=']';}
            if (c[i]=='{') {q[++top]=i; f[top]='}';}
            if ((c[i]==')'||c[i]==']'||c[i]=='}')&&top)
                if (f[top]!=c[i]) top=0;
                else
                {
                    for (j=q[top];j<=i;j++) f1[j]=1;
                    top--;
                }       
        }
        for (i=0;i<l;i++)
            if (f1[i]) s++;
            else
            {
                if (s>maxn) {maxn=s; mx=x;}
                s=0; x=i+1;
            }
        if (s>maxn) {maxn=s; mx=x;}
        for (i=mx;i<mx+maxn;i++) printf("%c",c[i]);
        return 0;
    }
    

    解法2:dp。
    呐,就是公式比较麻烦啦直接进代码。

    #include<cstdio>
    #include<cstring>
    int dp[5000005],maxn;
    char c[5000005];
    int main()
    {
        int i,l;
        scanf("%s",c);
        l=strlen(c);
        for (i=1;i<l;i++)
        {
            if ((c[i]==')'&&c[i-1-dp[i-1]]=='(')
              ||(c[i]==']'&&c[i-1-dp[i-1]]=='[')
              ||(c[i]=='}'&&c[i-1-dp[i-1]]=='{'))
                dp[i]=dp[i-1]+2/*处理嵌套*/+dp[i-2-dp[i-1]]/*处理并列*/;
            if (dp[i]>dp[maxn]) maxn=i;
        }
        for (i=maxn-dp[maxn]+1;i<=maxn;i++) printf("%c",c[i]);
        printf("\n");
        return 0;
    }
    
  • 1
    @ 2009-07-17 09:53:48

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 0ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:0ms

    其实无需这么复杂.

    设f[i]为第i个字符为末尾的和谐字串的最大长度,s[i]为原串.

    伪代码如下:

    if s[i] 为右括号 then

    if s 为配套的左括号 then f[i]=f+2

    else if s[i-f-1] 为配套的左括号 then

    f[i]=f+2;

    (若第i位之前有和谐字串,若这个和谐字串前为配套的左括号,那么从第i位开始的和谐字串的长度可以达到前面和谐字串的长度+2)

    最后只需把连续的字串连起来就可以了.复杂度为O(n).

    我的程序写的不好,但都可以做到只有30行.(pascal)

  • 0
    @ 2017-07-14 10:33:11

    本来我的思路是很清晰的,后来写着写着发现自己题目理解错了一半2333,顺带为啥我没有碰到套括号的优先级这中东西。。

    #include<iostream>
    #include<stack>
    #include<cstring>
    using namespace std;
    char stringData[5000000];
    bool Data[5000000];
    typedef struct slash{
        char Slash;
        int pos;
    }slash;
    stack<slash>check;
    int main(void){
        cin>>stringData;
        int index=0,ansBegin=0,ansEnd=0,length=0;
        while(stringData[index]!='\0'){
            if(stringData[index]=='('||stringData[index]=='['||stringData[index]=='{'){
                auto p=new slash;
                p->Slash=stringData[index];
                p->pos=index;
                check.push(*p);
            }
            else{
                if(check.size()==0){
                }
                else if((check.top().Slash=='('&&stringData[index]==')')||(check.top().Slash=='['&&stringData[index]==']')||
                (check.top().Slash=='{'&&stringData[index]=='}')){
                    {
                        ansBegin=check.top().pos;
                        ansEnd=index;
                        for(int i=ansBegin;i<=ansEnd;i++){
                            Data[i]=1;
                        }
                    }
                    check.pop();
                }
                else{
                    //clear the stack
                    int Size=check.size();
                    for(int i=0;i<Size;i++){
                        check.pop();
                    }
                }
            }
            index++;
        }
        int begin=0,end=0;
        for(int i=0;i<strlen(stringData);i++){
            if(i==0&&Data[i]==1){
                begin=0;
            }
            else if(Data[i]==1&&Data[i-1]==0){
                begin=i;
            }
            else if(Data[i]==1&&Data[i+1]==0){
                end=i;
                if(length<end-begin){
                    ansEnd=end;
                    ansBegin=begin;
                    length=ansEnd-ansBegin; 
                }
            }
        }
        for(int i=ansBegin;i<=ansEnd;i++){
            cout<<stringData[i];
        }
    } 
    
  • 0
    @ 2016-10-25 20:59:36

    拿测试数据和前人发过的AC代码我亲自测试,输出结果和output明明一模一样,tmd测评就是WA!!!!!!!!

  • 0
    @ 2016-09-13 11:30:01

    #include<stdio.h>
    #include<string.h>
    #include<stack>
    #include<algorithm>
    using namespace std;
    stack<char>a;
    stack<int>b;
    char bra[5000005];
    int main()
    {
    scanf("%s", bra);
    int len=strlen(bra);
    a.push(')');
    b.push(0);
    int i;
    for(i=0;i<=len;i++)
    {
    if(a.top()-bra[i]==-1||a.top()-bra[i]==-2)
    {
    a.pop();
    b.pop();
    }
    else
    {
    a.push(bra[i]);
    b.push(i+1);
    }
    }
    a.push('(');
    b.push(i+1);
    int max=0;
    int start;
    int end;
    while(b.top()!=0)
    {
    int tmp=b.top();
    b.pop();
    int tmp_=b.top();
    if(tmp-tmp_>=max)
    {
    start=tmp;
    end=tmp_;
    max=start-end-1;
    }
    }
    for(i=end;i<=start-2;i++)
    {
    printf("%c",bra[i]);
    }
    return 0;
    }

  • 0
    @ 2014-03-16 14:52:07

    编译通过...
    ├ 测试数据 01:答案正确... 0ms
    ├ 测试数据 02:答案正确... 0ms
    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 56ms

    Accepted 有效得分:100 有效耗时:56ms

  • 0
    @ 2009-10-31 14:40:30

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 56ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:56ms

    合并区间通用解法

    while (f[i]>0) and (ak[a[f[i]]]ak[a[i]]-1) do f[i]:=f[f[i]];

    if (f[i]>0) and (ak[a[f[i]]]=ak[a[i]]-1) then dec(f[i])

    else f[i]:=-1;

    while f[f[i]]>=0 do f[i]:=f[f[i]];

  • 0
    @ 2009-10-28 11:42:36

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 9ms

    直接用栈。。。 如果配对就弹栈

    再记下每一个压入栈的位置。

  • 0
    @ 2009-10-27 16:38:08

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:答案正确... 0ms

    ├ 测试数据 03:答案正确... 0ms

    ├ 测试数据 04:答案正确... 41ms

    ---|---|---|---|---|---|---|---|-

    Accepted 有效得分:100 有效耗时:41ms

    万分感谢 sdvsda 的帮助

  • 0
    @ 2009-10-06 18:59:10

    模拟栈即可!~~~~~

    同表达式计算过程一样。

  • 0
    @ 2009-08-12 11:08:55

    编译通过...

    ├ 测试数据 01:答案正确... 0ms

    ├ 测试数据 02:运行超时...

    ├ 测试数据 03:运行超时...

    ├ 测试数据 04:内存溢出...

    ---|---|---|---|---|---|---|---|-

    Unaccepted 有效得分:1 有效耗时:0ms

    MG~~

  • 0
    @ 2009-08-10 13:23:12

    ri。。。。题意有问题,其实同样长度有优先级的……太恶心了……

  • 0
    @ 2009-07-31 11:54:37

    开始把调试用的表交上去了,浪费一次提交。

    程序很短,只有26行。

    另外,非常感激sdvsdv神牛的详细题解!

  • 0
    @ 2009-08-16 16:25:30

    就按照大牛们的方法做

  • 0
    @ 2009-07-11 22:43:11

    ws题 强烈抗议

  • 0
    @ 2009-07-10 21:10:41

    怎么有点像‘迎春舞会之交谊舞’(1062)

  • 0
    @ 2009-07-10 21:10:11

    提醒各位:“套括号”优先于“并括号”!

  • 0
    @ 2009-07-11 11:53:51

    = = 囧

  • 0
    @ 2009-07-10 08:37:45

    强烈抗议把这题的输出更改成:

    最长和谐字串长度

    题目根本没讲清楚,如果有多个长度一样的该怎么输出。

    就算LX有人说并列优先于套起来,那么下面几个例子怎么办?

    1.{} 和 [] 输出哪个?

    2.{[]}[] 和 []{[]} 输出哪个?

  • 0
    @ 2009-07-09 22:00:37

    好吧 我承认 单纯栈是不行的 除非特殊处理~~~

    BS zgx 为什么会有多解。。。。

    1s的程序错了!!! 恭喜你 没有注意特殊情况

    给出几个优化:

    bs:=0;

    for i:=1 to l-1 do

    begin

    j:=ord(s)-ord(s[i]); 〈==看这两行

    if (j=1) or (j=2) then 〈==这个判断是利用ASCII码的

    begin

    bs:=bs+1; b[bs].x:=i; b[bs].y:=i+1;

    end;

    end;

    next:=true;

    while (next) do

    begin

    next:=false;

    for i:=1 to bs do

    if (b[i].x>1) and (b[i].y

信息

ID
1572
难度
7
分类
数据结构 | 点击显示
标签
(无)
递交数
1139
已通过
198
通过率
17%
被复制
3
上传者