约瑟夫环问题

本文探讨了著名的约瑟夫环问题,通过一个具体的实例演示了如何使用C语言编程解决这个问题。具体而言,13个人围成一圈,从第1个人开始报数,报到3的人退出圈子,直至所有人退出,输出退出顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

历史:

据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。


题目:

约瑟夫环问题。13个人围成一圈,从第一个开始报数,报到 “3”退出圈子,按顺序输出退出圈子的序号。


代码:

#include<stdio.h>
#include<math.h>
#define N 30
void Josephus();

void Josephus(int a[],int n,int s,int m)
/*约瑟夫问题,将出圈的人的序号依次存放在数组中*/
{
    int i,j,s1,t;
    s1=s;				/*开始报数的序号*/
    for(i=1;i<=n;i++)	/*初始化*/
		a[i-1]=i;
    for(i=n;i>=2;i--)	/*i为当前圈中的人数*/
	{
		s1=(s1+m-1)%i;	/*s1为将要出圈的序号*/
		if(s1==0)		/*如果s1=0说明,将要出圈的人的序号为s1*/
			s1=i;
		/*将序号s1的人出圈,即将序号为s1数移到到数组的末尾*/
		t=a[s1-1];
		for(j=s1;j<=i-1;j++)/*将s1后的数依次前移*/
			a[j-1]=a[j];
		a[i-1]=t;/*将序号为s1的数存储在a的末尾*/
	}
} 

void main()
{
	int i,a[N];
	int n=13,m=3,s=1;
	Josephus(a,n,s,m);
	printf("出圈的依次编号为:");
	for(i=n-1;i>=0;i--)
		printf("%-4d",a[i]);
	printf("\n");
}



输出:

出圈的依次编号为:3 6 9 12 2 7 11 4 10 5 1 8 13

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值