这几天在刷题的时候遇见了已到很经典的——约瑟夫环,所以顺便出一次题解防止自己忘记。
省流:看最后的完整代码。
原题:
报数模拟。
有n个人围成一个圈,从1到n按顺序排好号。然后从第一个人开始顺时针
报数(从1到3报数),报到3的人退出圈子后,后面的人继续从1到3报
数,直到留下最后一个人游戏结束,问最后留下的是原来第几号。
输入描述:输入一个正整数n(4<n<600)
输出描述:输出最后留下的人,原来的编号是多少?
【样例输入】
5
【样例输出】
3
虽然它自己说是报数模拟,但是本质是约瑟夫环。
解题过程:
1.大体思路:
假设我们又一个队列 nums 里面有5个数字,而我的老师给我提供的一个思路就是将前两个数字移到队尾,再删除队列的第一个数字。(如下图)
这样队列里就还剩下 4,5,1,2。第三个就寄(出队)了。
下面是实现这一步的代码。
//移动数据至队尾
//先出队再入队
temp = nums.front();
nums.pop();
nums.push(temp);
2.理论成立,实践开始:
按照题目要求,首先需要一个从 1~n 的队列;
#include <iostream>
#include <queue>
using namespace std;
int main(){
queue<int> nums;
//这里的 temp 只是一个临时变量,为后面的循环做铺垫
int n,temp;
cin>>n;
for (int i = 1; i<=n ;i++){
nums.push(i);
}
有了铺垫以后,开始代码的主体部分;
while (nums.size() != 1){
for (int i = 0; i<3-1 ;i++){
//出队再入队,将数据移至队尾
temp = nums.front();
nums.pop();
nums.push(temp);
}
nums.pop();
}
因为题目只要最后剩下的,所以套一个 while循环,就可以重复思路中讲的操作,最后就能得到结果,再输出。
cout<<nums.front();
下面是完整代码:
#include <iostream>
#include <queue>
using namespace std;
int main(){
queue<int> nums;
int n,temp;
cin>>n;
for (int i = 1; i<=n ;i++){
nums.push(i);
}
while (nums.size() != 1){
for (int i = 0; i<3-1 ;i++){
//出队再入队,将数据移至队尾
temp = nums.front();
nums.pop();
nums.push(temp);
}
nums.pop();
}
cout<<nums.front();
return 0;
}
最后还是:点赞!关注!(收藏就不必了)