约瑟夫环问题

前言

	简单问题,写的不好,大佬见谅.
	如有疏漏,恳请指正,小编垂首.

问题描述:

约瑟夫环问题:
有七个小朋友,分别编号是1,2,3…,7,按照从小到大顺时针围成一个圆圈,第一个小朋友从1开始报数,然后按照顺时针方向报数,每次报数增加一,每个报5的人会离开队伍,然后下一个小朋友从1开始报数,直到剩最小一个小朋友为止。

问题解析:

本题是一个f(m,n)问题,其中m为人数,n为间隔数

1 2 3 4 5 6 7
6 7 1 2 3 4
4 6 7 1 2 4 6 7 1 2
4 6 7 1 4 6 7 1
6 7 1 6 7 1
1 6 1 6 1 6
6
出局顺序为5 3 2 4 7 1

顺序思维很难找到规律,我们只能注意到新一轮的开始是由上一轮出局的人决定的
但由于每一轮都有人出局,所以无法用下标来记录,用计数来运算的话,可以使用循环链表实现
但我比较懒,不想写链表


所以列举一下找找y= f(m,n)的规律n = 5
m=1,y=0 (一个人怎么玩😒😭)
在这里插入图片描述
递归就好啦

实现代码:

代码如下(示例):

#include<iostream>
using namespace std;

int ysf(int n,int k) {
	if (n == 2) return k % 2;//若只有两人,则k为偶数,下标0存活,否则下标1存活
	return (k+ysf(n - 1, k)) % n;//从本轮死亡的人k开始数在n-1轮中存活的人的下标,对n取余,防止溢出
}
int main() {
	int n, k;
	cin >> n >> k;
	//约瑟夫环问题//返回的下标+1
	cout<<ysf(n, k)+1;

	return 0;
}

代码如下:
as everyone knows 递归可以写成循环(能不递归就不递归)

#include<iostream>
using namespace std;

int ysf(int n,int k) {
	int ans = 0;
	for (int i = 2; i <= n; i++) {
		ans = (k + ans) % i;
	}
	return ans;
}
int main() {
	int n, k;
	cin >> n >> k;
	//约瑟夫环问题//返回的下标+1
	cout<<ysf(n, k)+1;

	return 0;
}

注意事项

折腾了1个多小时,勉强用自己的思维理解了,但倒不出多少.
不会的小伙伴可以去看大佬的题解,

测试案例:

在这里插入图片描述

总结

正着不行,逆着来,只要有规律,总能找到

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

twfplayer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值