1 条题解

  • 0
    @ 2025-5-8 14:36:23

    这是一道关于排列组合和查找的问题,解题的关键在于生成所有可能的可爱栅栏排列,并根据目录编号找到对应的排列。

    算法标签

    排列组合、查找算法

    题解思路

    生成所有排列:使用 itertools.permutations 函数生成所有长度为 NN 的数字排列。 筛选可爱栅栏排列:定义 is_cute_permutation 函数,检查每个排列是否满足可爱栅栏的条件,即每个中间木板的高度要么大于相邻木板,要么小于相邻木板。 排序可爱栅栏排列:将筛选出的可爱栅栏排列按照题目规定的顺序进行排序。 查找对应排列:根据给定的目录编号 CC,在排序后的可爱栅栏排列中找到对应的排列。

    代码实现(c++)

    
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    int N;
    ll C;
    ll dp[21][21][2];
    bool used[21];
    int res[21];
    int main(){
        int Num;
        scanf("%d", &Num);
        dp[1][1][1] = dp[1][1][0] = 1;
        for(int i = 2; i <= 20; i ++){
            for(int j = 1; j<= i; j ++){
                for(int k = j; k <= i; k ++){
                    dp[i][j][1] += dp[i - 1][k][0];
                }
                for(int k = j - 1; k >= 1; k --){
                    dp[i][j][0] += dp[i - 1][k][1];
                }
            }
        }
        for(int num =0; num < Num; num ++){
            scanf("%d %lld", &N, &C);
            memset(used, 0, sizeof(used));
            ll skipped = 0;
            for(int i = 1; i <= N; i ++){
                ll old_val = skipped;
                int No = 0;
                for(int j = 1; j <= N; j ++){
                    old_val = skipped;
                    if(!used[j]){
                        No ++;
                        if(i == 1){
                            skipped += (dp[N][No][0] + dp[N][No][1]);
                        } else {
                            if(j > res[i - 1] && (i <= 2 || res[i - 2] > res[i - 1])){
                                skipped += dp[N - i + 1][No][0];
                            }
                            if(j < res[i - 1] && (i <= 2 || res[i - 2] < res[i - 1])){
                                skipped += dp[N - i + 1][No][1];
                            }
                        }
                        if(skipped >= C){
                            res[i] = j;
                            used[j] = true;
                            skipped = old_val;
                            break;
                        }
                    }
                }
            }
            for(int i = 1; i <= N; i ++){
                printf("%d ", res[i]);
            }
            printf("\n");
        }
    }
    
    • 1

    信息

    ID
    38
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者