目录
资源限制
内存限制: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;
}