试题 算法训练 筛选号码

目录

样例输入

样例输出

数据规模和约定

解题思路

图解

完整代码


资源限制

内存限制:512.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

问题描述

  有n个人围成一圈,顺序排号(编号为1到n)。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子。从下一个人开始继续报数,直到剩下最后一个人,游戏结束。
  问最后留下的是原来第几号的那位。
  举个例子,8个人围成一圈:
  1 2 3 4 5 6 7 8
  第1次报数之后,3退出,剩下:
  1 2 4 5 6 7 8 (现在从4开始报数)
  第2次报数之后,6退出,剩下:
  1 2 4 5 7 8 (现在从7开始报数)
  第3次报数之后,1退出,剩下:
  2 4 5 7 8 (现在从2开始报数)
  第4次报数之后,5退出,剩下:
  2 4 7 8 (现在从7开始报数)
  第5次报数之后,2退出,剩下:
  4 7 8 (现在从4开始报数)
  第6次报数之后,8退出,剩下:
  4 7 (现在从4开始报数)
  最后一次报数之后,4退出,剩下:
  7.
  所以,最后留下来的人编号是7。

输入格式

  一个正整数n,(1<n<10000)

输出格式

  一个正整数,最后留下来的那个人的编号。

样例输入

8

样例输出

7

数据规模和约定

  对于100%的数据,1<n<10000。

解题思路

        从第一个开始计数,计数为3的淘汰出局,从被淘汰的下一个人重新开始计数。此时,我们可以利用队列先进先出的特点来解答这道题。先定义一个变量k,用来计数,计的第一个数是1,所以k的初始值定义为1,然后在队列非空的情况下遍历队列,首先取出队首存储在一个变量中,然后将队首移除,如果当前计数对3取余不为0,即计数不是3的重新放回队列(此时,编号为3的编号已经被弹出队列),接在队尾,新加进去的第一个元素的计数可以易知为n+1,以此类推。最后输出最后一个被移除的元素,即为最后剩余的人的编号。

图解

完整代码

#include <iostream>
#include <queue>
using namespace std;
int main() {
    int n;
    cin >> n;
    queue<int> q;
    int i;
    for (i = 1; i <= n; i++) {
        q.push(i);
    }
    int p;
    int k = 1;              
    while (!q.empty()) {
        p = q.front();      //取队首
        q.pop();            //弹出队首
        if (k % 3 != 0) {    //从队首开始,把计数不为3的重新加入到队尾
            q.push(p);
        }
        k++;                //计数
    }
    cout << p;  // 输出队列中最后一个数
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值