1 条题解

  • 0
    @ 2025-8-24 21:14:25

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 一扶苏一
    休息结束。邮箱 yifusuyi@qq.com

    搬运于2025-08-24 21:14:24,当前版本为作者最后更新于2018-03-23 20:14:08,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    B3688 [语言月赛202212] 旋转排列 题解

    Source & Knowledge

    2022 年 12 月语言月赛,由洛谷网校入门计划/基础计划提供。

    本题考察循环结构。

    文字题解

    题目大意

    给出一个排列 pp,按如下规定循环操作:

    现在,给定一个长度为 nn 的排列 pp,请你按照如下规定循环操作:

    1. 对当前的排列 pp 做一次“shift”操作;
    2. 输出本次“shift”以后的排列 pp
    3. 判断排列 pp 的最后一个数字是否是 nn,如果是,则结束循环操作;否则回到 11 继续操作。

    一次“shift”操作是指:将 pp 里的每一个数字都依次向后移动一位,并把 pp 的最后一个数字移动到开头去。

    解析

    shift 操作

    考虑一次 shift 操作如何完成:可以令 i:=ni := n22 进行倒序枚举,每次令 p[i]:=p[i1]p[i] := p[i - 1],这样可以把第 1(n1)1 \sim (n-1) 的数字都向后移一位。但是此时原有的 p[n]p[n] 的值会被抹去, 需要新建一个变量 temptemp 来存储 p[n]p[n] 的值,再枚举结束后直接令 p[1]:=tempp[1] := temp

    核心代码为:

    int temp = p[n];
    for (int i = n; i >= 2; --i) p[i] = p[i - 1];
    p[1] = temp;
    

    输出操作

    需要输出一行 nn 个数,两两之间用空格隔开,行末输出空格。可以采用如下的输出形式:

    for (int i = 1; i <= n; ++i) {
      cout << p[i] << " \n"[i == n];
    }
    

    在上文的代码中," \n" 是一个长度为 22 的字符串,其第 00 位为空格,第 11 位为换行。我们可以用 [] 运算符来访问其某一位。

    ini \neq n 时,语句 i == n 的值为 00,此时相当于 " \n"[0],则输出一个空格;
    i=ni = n 时,语句 i == n 的值为 11,此时相当于 " \n"[1],则输出换行符。

    循环操作

    注意到循环操作的要求:先执行循环体,再进行判断。这提示我们使用 do - while 语句。

    do - while 语句的结构是 do A while (B),代码会先执行语句(块) A(无论 B 是否为真),再执行判断语句 B,如果 B 为假,则终止执行,否则反复执行语句(块)A 直到 B 为假。

    结合上面的分析,我们可以写出循环部分的核心代码:

    do {
      int temp = p[n];
      for (int i = n; i >= 2; --i) p[i] = p[i - 1];
      p[1] = temp;
      for (int i = 1; i <= n; ++i) {
        cout << p[i] << " \n"[i == n];
      }
    } while (p[n] != n);
    

    视频题解

    完整代码请在视频中查看。

    • 1

    信息

    ID
    8182
    时间
    1000ms
    内存
    512MiB
    难度
    1
    标签
    递交数
    0
    已通过
    0
    上传者