约瑟夫环(C++)

157 阅读1分钟

这几天在刷题的时候遇见了已到很经典的——约瑟夫环,所以顺便出一次题解防止自己忘记。

省流:看最后的完整代码。 原题: 报数模拟。

有n个人围成一个圈,从1到n按顺序排好号。然后从第一个人开始顺时针

报数(从1到3报数),报到3的人退出圈子后,后面的人继续从1到3报

数,直到留下最后一个人游戏结束,问最后留下的是原来第几号。

输入描述:输入一个正整数n(4<n<600)

输出描述:输出最后留下的人,原来的编号是多少?

【样例输入】

5

【样例输出】

3

虽然它自己说是报数模拟,但是本质是约瑟夫环。

解题过程:

1.大体思路: 假设我们又一个队列 nums 里面有5个数字,而我的老师给我提供的一个思路就是将前两个数字移到队尾,再删除队列的第一个数字。

下面是实现这一步的代码: //移动数据至队尾 //先出队再入队 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 #include 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;

} ` 最后还是:点赞!关注!(收藏就不必了) 原文链接:blog.csdn.net/TT081227/ar… (虽然也是我写的,但是从CSDN上搬过来要加原文链接 >_<)