zoukankan      html  css  js  c++  java
  • 括号序列

    括号序列

    brackets.c/cpp/pas

    2s/256M)

    【题目描述】

    课堂上Felix刚刚学习了关于括号序列的知识。括号序列一个只由左括号“(”和右括号“)”构成的序列;进一步的,一个合法的括号序列是指左括号和右括号能够一一匹配的序列。

    如果用规范的语言说明,一个合法的括号序列可以有以下三种形式:

    1 S=“”(空串),S一个合法的括号序列;

    2 S=XY,其中XY均为合法的括号序列,则S也是一个合法的括号序列;

    3 S=(X)其中X为合法的括号序列,则S也是一个合法的括号序列。

    老师在黑板上写出了一个了括号序列:“()))()”

    Felix一眼就看出这个序列并不是合法的括号序列。

    这时老师提出了一个这样的问题:能否在序列中找出连续的一段,这一段里面的左括号变成右括号,右括号变成左括号,变换之后整个序列可以变合法的呢?

    Felix想到可以把[3..5]进行调换,这样序列就会变为()(())是一个合法的序列。很明显,不止有一种方法可以使整个序列变合法。

    这时老师又在黑板上写出了一个长度为N的括号序列。Felix想,能否对这个序列进行至多一次变换,使它合法呢?

    输入格式】brackets.in

    第一行一个整数T代表数据的组数;接下来T行,每一行一组数据。

    每组数据一行,代表给出的括号序列。

    【输出格式brackets.out

    输出共T行,对于每组数据,输出“possible”(可以变换)或“impossible”(不可变换)。(不含引号)

    【样例输入】

    3

    ()))

    )))(

    ()

    【样例输出】

    possible

    impossible

    possible

    【数据范围与约束】

    对于50%的数据,T<=5, N<=20;

    对于100%的数据,T<=10, N<=5000.

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int N = 5005;
    int n;
    int a[N];
    int f[2][N][3];
    string s;
    void first()
    {
        cin>>s;
         n=s.size();
        for(int i=0;i<n;i++)
        if(s[i]=='(')    a[i]=1;
        else a[i]=-1;    
    }
    void work()
    {
        memset(f,0,sizeof f); 
        f[0][0][0]=1;
        bool pre=0;
        for(int i=0;i<n;i++)
        {
            memset(f[!pre],0,sizeof f[!pre]);
            for(int j=0;j<=i&&i+j<=n;j++)
            {
                if(f[pre][j][0])
                {
                    if(a[i]<0&&j>0)    f[!pre][j-1][0]=1;
                    else if(a[i]>0) f[!pre][j+1][0]=1;
                    
                    if(a[i]>0&&j>0) f[!pre][j-1][1]=1;
                    else if(a[i]<0) f[!pre][j+1][1]=1;
                }
                if(f[pre][j][1])
                {
                    if(a[i]>0&&j>0)    f[!pre][j-1][1]=1;
                    else if(a[i]<0)    f[!pre][j+1][1]=1;
                    
                    if(a[i]<0&&j>0)    f[!pre][j-1][2]=1;
                    else if(a[i]>0) f[!pre][j+1][2]=1;                
                }
                if(f[pre][j][2])
                {
                    if(a[i]<0&&j>0)    f[!pre][j-1][2]=1;
                    else if(a[i]>0) f[!pre][j+1][2]=1;            
                }
                
            }
            pre=!pre;
        }
        int  ok=  f[pre][0][0] | f[pre][0][1] | f[pre][0][2];
        if(ok) printf("possible
    ");
        else printf("impossible
    ");
        return ;
    }
    int  main()
    {
        freopen("brackets.in","r",stdin);
        freopen("brackets.ans","w",stdout);
        int t;
        scanf("%d",&t);
        while(t--)
        {
            first();
            work();
        }
        return 0;
    } 
  • 相关阅读:
    3.09_面向对象(包、修饰符和内部类)
    3.08_面向对象(多态的概述及其代码体现)
    3.07_面向对象(继承)
    3.06_面向对象(代码块的概述和分类)
    3.05_面向对象(java文档说明书的制作过程)
    3.04_面向对象基础((main方法的格式详细解释)
    3.03_面向对象(static关键字及内存图)
    3.02面向对象(创建一个对象的步骤)
    3.01_面向对象基础(构造方法)
    2.02_Java语言基础(循环结构概述)
  • 原文地址:https://www.cnblogs.com/CLGYPYJ/p/7716912.html
Copyright © 2011-2022 走看看