约瑟夫环——C++

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

省流:看最后的完整代码。

 原题:

报数模拟。

有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;
} 

最后还是:点赞!关注!(收藏就不必了)

  • 12
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值