c++解决约瑟夫环问题

c++解决约瑟夫环问题

问题背景

约瑟夫(Josephus)问题:

  1.  m个人围坐成一圈,从1开始顺序编号
    
  2.  游戏开始,从第一个人开始由1到n循环报数 
    
  3.   报到m的人退出圈外
    

问:
最后留下的那个人原来的序号

问题分析

本题可以定义一个容器(vector),初始化大小(元素个数)为n。容器里元素的值标识该人是否出局,1在圈内,0出局。值为0的人不再参与报数,可以用一个整数型k做计数器,采用倒计数,记录留下的人数。

代码解决

引用库

#include
#include
using namespace std;

利用一个main函数解决问题,并完成初始化

int main()
{
	int m,n,k,p,number=0,i;
	cout << "请输入总人数m以及循环号码n:";
	cin >> m >> n;
	k = m;
	vector<bool> left(m, 1);

m表示总人数,n表示报数的号码,k对应场内剩余的人数,number代表每一轮开始报数的位置,i作为中间量在后续代码中被使用。

while (k > 1)
	{
		i = number;				//i记录循环开始位置
		number = n % k - 1;		//number 记录要往后移动几个人
		if (number < 0) number += n;
		for (int j = 1; j <= number; i++)
		{
			if (left[(i + j) % m] != 0) j++;
		}
		left[i % m] = 0;				//找到最后一个并置零
		p = i + 1;						//寻找下一个循环开始位置
		while (1)
		{
			if (left[p % m] != 0) break;
			else p++;
		}
		number = p%m;
		k--;
	}

注意:报数过程和开始下次报数时都要进行判断,当前所在位置其值是否为0,若为0则要跳过。

以下是最终的完整代码

#include
#include
using namespace std;
int main()
{
	int m,n,k,p,number=0,i;
	cout << "请输入总人数m以及循环号码n:";
	cin >> m >> n;
	k = m;
	vector<bool> left(m, 1);
	while (k > 1)
	{
		i = number;				//i记录循环开始位置
		number = n % k - 1;		//number 记录要往后移动几个人
		if (number < 0) number += n;
		for (int j = 1; j <= number; i++)
		{
			if (left[(i + j) % m] != 0) j++;
		}
		left[i % m] = 0;				//找到最后一个并置零
		p = i + 1;						//寻找下一个循环开始位置
		while (1)
		{
			if (left[p % m] != 0) break;
			else p++;
		}
		number = p%m;
		k--;
	}
	cout << "最后剩下的人为:" << number + 1 << "号";
	return 0;
}

欢迎指正

你可能感兴趣的:(c++解决约瑟夫环问题)