top1编程
← 返回题目
题解

密码升级

1 条题解

  • 0
    @ 2026-8-6 2:22:20

    P4843 密码升级(入门)

    解题思路

    **第一步,把8位数字看成排队。**我们把这8个数字依次放进队列里,就像食堂里排队打饭的同学。队列的队头用h表示,队尾用t表示,新同学排在队尾。

    **第二步,按规则“动起来”。**规则说:把第1个数字删除,第2个数字放到数字末端,再把第3个数字放到数字末端。换成队列的语言就是:先把队头同学“请出队”并记下他的编号(这就是密码的一位);然后从队头再走一个同学,让他绕到队尾重新排队;接着再从队头走一个同学,也绕到队尾。这样重复做,直到队列里没有同学为止。

    **第三步,为什么这样做就是密码?**因为我们每次请出队的那个人,正好是当前队伍里的“第1个数字”,把他依次记下来,连在一起就是生成的密码。

    **第四步,注意小陷阱。**每次请出1个人,再移动2个人到队尾,队伍里的人数会越来越少。当队伍里只剩1个人的时候,把他请出队就可以结束了,这时队列已经空了,不需要再移动任何人。所以写代码时每步之前都要检查一下队列是不是空的。

    **举例子验证。**输入 20230206:第一步请出2,0和2绕到队尾,队伍变成 3020620;第二步请出3,队伍变成 062022……按这个规律,最后请出的人依次是 2、3、0、2、6、2、0、0,组成的密码是 23026200,和样例一致。

    参考代码

    // P4843 密码升级:删掉第1个数字输出,再把第2、第3个数字依次放到末端
    #include <iostream>
    #include <cstdio>
    using namespace std;
    char s[20];
    char q[30];
    int h, t;
    int main() {
        scanf("%s", s);
        for (int i = 0; s[i]; i++) q[t++] = s[i];  // 8位数字全部入队
        while (h < t) {
            printf("%c", q[h++]);        // 删除第1个数字并输出
            if (h < t) q[t++] = q[h++];  // 第2个数字放到末端
            if (h < t) q[t++] = q[h++];  // 第3个数字放到末端
        }
        printf("\n");
        return 0;
    }
    

    复杂度分析

    一共只有8位数字,每次循环请出1个、移走2个,最多循环8次就全部结束,时间可以看成O(8),也就是常数时间。空间只用一个长度30的字符数组来模拟队列,绰绰有余。

    • 1