题解
密码升级
1 条题解
-
0
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