【C语言】约瑟夫环问题

本文详细介绍了如何使用C语言解决经典的约瑟夫环问题,通过链接列表实现,深入探讨了算法逻辑和数据结构的应用。

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

看这篇博客后https://blog.youkuaiyun.com/yanweibujian/article/details/50876631?utm_source=app照自己理解写的。

/* 约瑟夫环问题 */

/*
问题描述:
	有10个人,每次报到3的人被杀掉,被杀掉的人的下一个人重新开始从1数,求最后幸存的那个人。
	如:
			     报数为3的人
			        ||
			        \/
			1: 0 1 【2】 3 4 5 6 7 8 9
			2: 3 4 【5】 6 7 8 9 0 1
			3: 6 7 【8】 9 0 1 3 4
			4: 9 0 【1】 3 4 6 7
			5: 3 4 【6】 7 9 0
			6: 7 9 【0】 3 4
			7: 3 4 【7】 9
			8: 9 3 【4】
			9: 9 3 【9】
	最后剩下的人是编号为4的人

	方法一:使用循环链表去模拟,但是当要有m个人,报到n个数时,就要循环(n * (m - 1))次,复杂度高,想想能不能直接定位要杀掉的人的编号,
		那样就不用去模拟数到3的位置是哪个。显然还是使用环形队列的去模拟这个过程,可以使用数组去存储,那么就会产生这样的情况:
			每次杀掉的那个人就是在数组下标为2的人。数组头就会存放成为下标为3的位置的数,这里面存在一个映射关系:

			旧数组下标	0	1	2	3	4	5	6	7	8	9	杀掉一个以后------>
			新数组下标	7	8		0	1	2	3	4	5	6	杀掉一个以后------>
			更新的下标	4	5		6	7		0	1	2	3	杀掉一个以后------>
						1	2		3	4		5	6		0	杀掉一个以后------>
						5			0	1		2	3		4	杀掉一个以后------>
						2			3	4			0		1	杀掉一个以后------>
									0	1			2		3	杀掉一个以后------>
									1	2					0	杀掉一个以后------>
									1						0	杀掉一个以后------>
									1
					因为:(旧数组下标 - 3) % (10 - 1) = 新数组下标		PS:因为是环形队列,所以下标为0 1 的那两个相当于是10 11
					所以:旧数组下标 = (新数组下标 + 3) % 10;
					则:当表示m个人,报到n就被杀时:
						old = (new + n) % m;
						再看一下old与new的关系:
							old可以表示的是m个人,报到数为n,
							new表示m - 1个人,报到数为n。    PS:因为新数组也是从0 - 8;
							那么:
								f(m, n)表示m个人,报到n时数组的下标。
								f(m, n) = (f(m - 1, n) + n) % m;

							那么可以映射他们之间的任意的下标关系。

					如果使用f(m, n, p)来表示第p个被杀的人。
						f(m, n, 1) = (n - 1) % m;
						f(m, n, 2) = (f(m - 1, n, 2 - 1) + n)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值