约瑟夫环(Joseph环)公式推导C语言版

约瑟夫问题:

——n个人围成一圈,第一个人从1开始报数,报m的将被杀掉,下一个人接着从1开始报。如此反复,最后剩下一个,求最后的胜利者。

解法:

——该内容略版,详解请参看大佬博客

——递推公式:

        Joseph(n,m)=(Joseph(n−1,m)+m)%n
        
f(n,m)表示:
n个人报数,每报到m时杀掉那个人,返回最终胜利者的编号。
f(n−1,m)表示:
n-1个人报数,每报到M时杀掉那个人,返回最终胜利者的编号。

——显而易见,上述是一个递归的过程,当有n个人时,是不能确定谁最终能存活,只有剩下一个时,才会知道谁最终活了下来。

——下面举例子模拟:11个人,报3的死亡。

			下图为模拟过程,绿色为下标。

在这里插入图片描述

	可只看黄色部分的左边(包括黄色部分),
	黄色部分右边部分作用不是很大,方便理解过程。

——下面就从下向上看:盯住胜利者的下标变化。
—— 从图中可知最后胜利者为7,对应的下标为0。

  1. 只有1个人报数时,胜利者处于首位,下标为0。
    即Joseph(1,3)=0;
  2. 下面变成2个人报数,胜利者需在0号位向右移动3位,因为不能越界,最终胜利者位于1号位置。
    即Joseph(2,3)=(Joseph(1,3)+3)%2;
  3. 下面变成3个人报数,胜利者从1号位置向右移动3位,最终仍然处于1号位。
  4. 下面变成11个人报数,胜利者处于6号位置。即从一开始这个位置上的人就注定不会死。

代码1:(递归)

#include<stdio.h>
int Joseph(int n,int m)
{
	if(n==1)
		return 0;
	else
		return (Joseph(n-1,m)+m)%n;
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	int p=Joseph(n,m);
	printf("%d\n",p+1);
	return 0;
}

代码2:(非递归)

#include<stdio.h>
int main()
{
	int n,m,i,p=0;
	scanf("%d %d",&n,&m);
	for(i=2;i<=n;i++)
    	p=(p+m)%i;
	printf("%d\n",p+1);
	return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值