专栏文章

题解:CF2118B 制作排列矩阵

CF2118B题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mip3ay11
此快照首次捕获于
2025/12/03 05:28
3 个月前
此快照最后确认于
2025/12/03 05:28
3 个月前
查看原文

简要题意

给出一个 n×nn\times n 的矩阵,其中 ai,j=ja_{i,j}=j。可以进行若干次操作,每次操作将某一行内的一段区间翻转,求使得矩阵每一列数字刚好满足 11nn 各出现一次的最少操作次数,并输出每一步的操作。

思路

考虑这么一种构造方法:
n=5n=5 的情况为例,下面的矩阵显然符合要求:
1 5 4 3 22 1 5 4 33 2 1 5 44 3 2 1 55 4 3 2 11~5~4~3~2\\2~1~5~4~3\\3~2~1~5~4\\4~3~2~1~5\\5~4~3~2~1
分析样例可知,我们只需要对每一行的 [1,i][1,i][i+1,n][i+1,n] 这两个区间翻转即可。
在此基础上,我们发现当 ii11,操作 [1,1][1, 1] 的区间长度为 11,这样白白浪费了一次操作次数;同理,当 iinn 时,操作 [n+1,n][n+1,n] 是无意义的。因此最终答案为 2n22n-2,操作方法为:
  • i=1i=1,只执行 1 2 n1~2~n
  • 2i<n2\le i<n,执行 i 1 ii~1~ii i+1 ni~i+1~n
  • i=ni=n,只执行 n 1 nn~1~n
CPP
#include <bits/stdc++.h>
using namespace std;
int t, x;
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        scanf("%d", &x);
        printf("%d\n", 2*x-2);
        printf("%d %d %d\n", 1, 2, x);
        for (int i = 2; i < x; i++)
        {
            printf("%d %d %d\n%d %d %d\n", i, 1, i, i, i+1, x);
        }
        printf("%d %d %d\n", x, 1, x);
    }
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...