约瑟夫问题思路记录

约瑟夫问题

n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈,请输出依次出圈人的编号。

输入格式:

输入两个整数 n,m。

输出格式:

输出一行 n 个整数,按顺序输出每个出圈人的编号。


说明/提示

1<=n,m<=100

输入样例:

10 3

输出样例:

3 6 9 2 7 1 8 5 10 4

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

栈限制

8192 KB

遇到了这道很经典的线性表问题,对于这类问题可以有两种解答方式,暴力模拟和队列数组有一些很好用的函数。

首先是暴力模拟 

#include <bits/stdc++.h>
using namespace std;
int n,m,counts,p=0,p2;
int main(){
	cin>>n>>m;
	bool round[n]={0};
	while(counts<n){
		do{
			p2=(p2+1>n?1:p2+1);
		}while(round[p2]==1);
		p=(p+1>m?1:p+1);
		if(p==m){
			round[p2]=1;
			counts++;
			cout<<p2<<' ';
		}
	}
}

队列数组是

 

#include <bits/stdc++.h>
using namespace std;
queue<int> q;
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		q.push(i);
	}
	int counts=0;
	int p=0;
	while(counts<n){
		p=(p+1>m?1:p+1);
		if(p==m){
			cout<<q.front()<<' ';
			q.pop();
			counts++;
		}else{
			q.push(q.front());
			q.pop();
		}
	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值