• 【POJ1068】Parencodings


    题目传送门

    本题知识点:模拟

    这是一道恐怖的括号题。题意稍微理解以下还是可以的。

    我们针对样例来理解一下 S、P、W 到底是什么意思:

    S:( ( ( ( ) ( ) ( ) ) ) )

    P:

    (P_1) 为 4 :是因为在第一个 ) (数组第4位)前面有4个 (

    (P_2) 为 5 :是因为在第二个 ) (数组第6位)前面有5个 (

    (P_3) 为 6 :是因为在第三个 ) (数组第8位)前面有6个 (

    (后面 (P_4) (P_5) (P_6) 情况跟 (P_3) 是一样的,所以不重复啰嗦了)

    W:

    (W_i) 表示的是括号数,为了表示清楚一点下面用粗体标清楚

    (W_1) 为 1:是因为 ( ( ( ( ) ( ) ( ) ) ) ) 在与第一个 ) 前面的 ( 只形成了 1 个 ( )

    (W_2) (W_3) 情况跟 (W_1) 一样)

    (W_4) 为 4:是因为 ( ( ( ( ) ( ) ( ) ) ) ) 第 4 个 ) 与数组第 2 位的 ( 配对了,除了它们俩一对外,它们还包含了里面 3 对,所以是 4 对

    为什么第 4 个不能与数组第 7 位的 ( 配对?因为第 7 位的已经跟前面的 ) 配对了。

    相信看到这里就算没读懂题意的你也有一点开窍了。从第一个 ) 开始,与它最相近的 ( 进行配对,配对之后就不能让后者配对了。所以我们这里可以弄一个bool数组来记录 ( 是否已经配对。

    在此之前,我们还要先构造出 S 的字符串,这个构造比较简单,请结合代码思考一下。

    随后就遍历一下 S 字符串,再记录一下每个 ) 所对应的答案即可。

    数据很小,这种暴力解题没有问题!

    // POJ 1068
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    int T, n;
    int P[25], W[25], pla[25];
    char pra[50];
    bool take[50];
    
    int main()
    {
        scanf("%d", &T);
        while(T--){
            memset(take, false, sizeof(take));
            scanf("%d", &n);
            for(int i = 0; i < n; i++) scanf("%d", &P[i]);
    
            // 构造 S 字符串
            int left = 0, i = 0, k = 0;
            while(i < n){
                if(left == P[i]){
                    pra[k++] = ')';
                    i++;
                }
                else {
                    pra[k++] = '(';
                    left++;
                }
            }
    
            // 记录每个 ) 的位置
            int cnt = 0, c = 0;
            for(int i = 0; i < n * 2; i++){
                if(pra[i] == ')') {
                    pla[cnt++] = i;
                }
            }
    
            // 最终遍历找答案
            for(int i = 0; i < cnt; i++){
                int j = pla[i], ans = 0;
                while(j >= 0){
                    if(pra[j] == '('){
                        ans++;
                        if(!take[j]){
                            W[c++] = ans;
                            take[j] = true;
                            break;
                        }
                    }
                    j--;
                }
            }
    
            for(int i = 0; i < c; i++){
                printf("%d%c", W[i], i != c - 1 ? ' ' : '
    ');
            }
    
        }
        return 0;
    }
    
    
  • 相关阅读:
    Android由一个activity 间隔5秒自动跳转到另外一个activity
    ZXing二维码的生成和解析
    JAVA生成条形码
    JAVA生成带Logo的二维码
    JAVA操作MongoDB数据库
    MongoDB数据库的简介及安装
    Redis在windows下的安装使用
    class关键字
    遍历器接口
    Promise对象
  • 原文地址:https://www.cnblogs.com/Ayanowww/p/11530664.html
Copyright © 2020-2023  润新知