写在前面:仅为个人代码/总结,未必标准,仅供参考!如有错误,还望指出交流,共同进步!
游戏
【问题描述】
基于STL实现以下功能:有n个小朋友围成一圈玩游戏,小朋友从1至n编号,2号小朋友坐在1号小朋友的顺时针方向,3号小朋友坐在2号小朋友的顺时针方向,……,1号小朋友坐在n号小朋友的顺时针方向。
游戏开始,从1号小朋友开始顺时针报数,接下来每个小朋友的报数是上一个小朋友报的数加1。若一个小朋友报的数为k的倍数或其末位数(即数的个位)为k,则该小朋友被淘汰出局,不再参加以后的报数。当游戏中只剩下一个小朋友时,该小朋友获胜。
例如,当n=5, k=2时:
1号小朋友报数1;
2号小朋友报数2淘汰;
3号小朋友报数3;
4号小朋友报数4淘汰;
5号小朋友报数5;
1号小朋友报数6淘汰;
3号小朋友报数7;
5号小朋友报数8淘汰;
3号小朋友获胜。
给定n和k,请问最后获胜的小朋友编号为多少?
【问题分析】
① 处理对象:值分别为1-n的n个数据
② 实现的功能:基于STL实现解决约瑟夫问题的功能
③ 结果的显示:输出胜利者的编号
④ 算法思想:将n个编号的小朋友排成一个循环队列,从编号1的小朋友开始依次出队并从1开始报数,当出队的小朋友所报的数不是k的倍数或其末位数(即数的个位)为k,则将该小朋友从队尾回到队列中,当队列只剩下一个小朋友时则该小朋友为最后的胜利者。
样例求解过程:
(注,队列为循环队列,每行后的数字为实时队列)
原队列:1 2 3 4 5 6 7
1号小朋友报数1,出队后入队;2 3 4 5 6 7 1
2号小朋友报数2,出队后入队;3 4 5 6 7 1 2
3号小朋友报数3,直接出队淘汰;4 5 6 7 1 2
4号小朋友报数4,出队后入队;5 6 7 1 2 4
5号小朋友报数5,出队后入队;6 7 1 2 4 5
6号小朋友报6,直接出队淘汰;7 1 2 4 5
7号小朋友报数7,出队后入队;1 2 4 5 7
1号小朋友报数8,出队后入队;2 4 5 7 1
2号小朋友报数9,直接出队淘汰;4 5 7 1
4号小朋友报数10,出队后入队;5 7 1 4
5号小朋友报数11,出队后入队;7 1 4 5
7号小朋友报数12,直接出队淘汰;1 4 5
1号小朋友报数13,直接出队淘汰;4 5
4号小朋友报数14,出队后入队;5 4
5号小朋友报数15,直接出队淘汰;4
4号小朋友获胜。
【参考代码】
#include <iostream>
#include <queue>
using namespace std;
int main()
{
int n,k;
cin>>n>>k;
queue <int> Q;
for(int i=1;i<=n;i++)
{
Q.push(i);
}
int num=1;
while(Q.size()>1)
{
int fro=Q.front();
Q.pop();
if(num%k!=0&&num%10!=k)
{
Q.push(fro);
}
num++;
}
cout<<Q.front()<<endl;
return 0;
}
此文章和之前发布过的文章约瑟夫问题(单向链表解法&队列法)和数七小游戏同属于对约瑟夫问题的解决,可通过对比三篇文章的解法加深对约瑟夫问题的了解