数据结构--约瑟夫环问题

题目描述

约瑟夫环来源

首先,我们先来了解一下什么是约瑟夫环问题:
讲一个比较有意思的故事:约瑟夫是犹太军队的一个将军,在反抗罗马的起义中,他所率领的军队被击溃,只剩下残余的部队40余人,他们都是宁死不屈的人,所以不愿投降做叛徒。一群人表决说要死,所以用一种策略来先后kill所有人。
于是约瑟夫建议:每次由其他两人一起kill一个人,而被kill的人的先后顺序是由抽签决定的,约瑟夫有预谋地抽到了最后一签,在kill了除了他和剩余那个人之外的最后一人,他劝服了另外一个没死的人投降了罗马。

题目如下:

编号为1,2,…,n的n个人按顺时针方向围坐在一张圆桌周围,每人持有一个密码(正整数)。

开始任选一个正整数m作为报数上限值,从第一个人开始按顺时针方向自1开始报数,报到m时停止报数,报m的那

个人出列,将他的密码作为新的m值,从他顺时针方向的下一个人开始重新从1报数,数到m的那个人又出列;如

此下去,直至圆桌周围的人全部出列为止。要求按出列顺序输出n个人的编号。

输入:

第一行输入两个整数,依次表示人数n和初始化密码m,以空格间隔。

第二行依次输入n个整数,分别表示n个人的密码,以空格间隔。

7 20
3 1 7 2 4 8 4
输出:

按出列次序输出每个人的编号,以空格间隔。

6 1 4 7 2 3 5

方法一:数组

使用数组解决,对于数组的长度进行取余。
实现:线性存储看做环式
或者利用递推公式 每次删除的点的下标 i=i+m-1;

方法二:单向循环链表

建立单向循环链表时建议使用尾结点:
1.操作统一
2.时间复杂度。头找尾O(n),尾找头O(1)。

#include<stdio.h>
#include<stdlib.h>
typedef struct node{
   
	int data;
	int password;
	struct node *next;
}ElemSN;
ElemSN * Create();	
int n,m;			//创建约瑟夫环
void Josephus(ElemSN * tail);
int main(void){
   
	ElemSN *tail;				//利用尾结点保证创建链表时操作的一致性(不用对第一个结点进行特殊判断) 
	tail=Create();
	Josephus(tail);
}
ElemSN * Create(
  • 13
    点赞
  • 124
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值