Josephus问题(数组方法)(最简易答案)

num 个人围坐在圆桌周围,现在从第 n 个人开始报数,数到第 interval 的人出列,然后从出列的下一个人重新开始报数,数到第 interval 的人又出列,如此重复直到所有的人全部出列为止

当输入 interval 后,求最后胜出的人(打印其下标)

#include <iostream>
using namespace std;

int main()
{
	int num;
	cout<<"Josephus圈共多少人:"; 
	cin >> num;
	int a[num];
	for (int i = 0; i < num; i++)
	{
		a[i] = i + 1;
	}
	cout << "几个人算一轮:";
	int interval;
	cin >> interval;
	for (int i = 0; i < num; i++)
	{
		cout << a[i] << ",";
	}
	cout << endl;
	int i;
	cout<<"从第几个人开始数:";
	cin >> i; 
	i = i-2;                              为了确保从第 n 个人开始报数
	for(int k = 1; k < num; k++)         轮数,num-1 轮(为了剩下一个人)
	{
		for(int j = 0; j < interval;)     每数 interval 个数淘汰一个人
		{
			i = (i+1) % num;        取模是为了保证淘汰人的下标永远在 num 的范围内
			if(a[i]!=0)                           跳过淘汰的人
			{
				j++;
			}
		}
		cout<<a[i]<<"被淘汰掉了"<<endl; 
		a[i] = 0;
	}
	for (int i = 0; i < num; i++)         打印不为 0 的元素即最后胜出的人
	{
		if(a[i] != 0)
		{
			cout<<a[i]<<"是winner!"; 
		}
	}
	return 0;
}
Input

Josephus圈共多少人:10
几个人算一轮:3
1,2,3,4,5,6,7,8,9,10,
从第几个人开始数:1

Output

3被淘汰掉了
6被淘汰掉了
9被淘汰掉了
2被淘汰掉了
7被淘汰掉了
1被淘汰掉了
8被淘汰掉了
5被淘汰掉了
10被淘汰掉了
4是winner!

用到了取模的方法

核心思想就是:将淘汰的人标记为 0 ,一直循环、标记,直到只剩一个人为止

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值