约瑟夫斯问题

✍ dations ◷ 2025-11-16 03:05:30 #约瑟夫斯问题

阿橋问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为约瑟夫环。

人们站在一个等待被处决的圈子里。 计数从圆圈中的指定点开始,并沿指定方向围绕圆圈进行。 在跳过指定数量的人之后,处刑下一个人。 对剩下的人重复该过程,从下一个人开始,朝同一方向跳过相同数量的人,直到只剩下一个人,并被释放。

问题即,给定人数、起点、方向和要跳过的数字,选择初始圆圈中的位置以避免被处决。

这个问题是以弗拉维奥·约瑟夫命名的,他是1世纪的一名犹太历史学家。他在自己的日记中写道,他和他的40个战友被罗马军队包围在洞中。他们讨论是自杀还是被俘,最终决定自杀,并以抽签的方式决定谁杀掉谁。约瑟夫斯和另外一个人是最后两个留下的人。约瑟夫斯说服了那个人,他们将向罗马军队投降,不再自杀。约瑟夫斯把他的存活归因于运气或天意,他不知道是哪一个。

比较简单的做法是用循环单链表模拟整个过程,时间复杂度是O(n*m)。如果只是想求得最后剩下的人,则可以用数学推导的方式得出公式。且先看看模拟过程的解法。

# -*- coding: utf-8 -*- class Node(object):	def __init__(self, value):		self.value = value 		self.next = Nonedef create_linkList(n):	head = Node(1)	pre = head	for i in range(2, n+1):		newNode = Node(i)		pre.next= newNode		pre = newNode	pre.next = head	return headn = 5 #總的個數m = 2 #數的數目if m == 1: #如果是1的话,特殊處理,直接輸出	print (n)  else:	head = create_linkList(n)	pre = None	cur = head	while cur.next != cur: #终止條件是節點的下一个節點指向本身		for i in range(m-1):			pre =  cur			cur = cur.next		print (cur.value)		pre.next = cur.next		cur.next = None		cur = pre.next	print (cur.value)

C++版本

#include <iostream>#include <cstdlib>#include <cstdio>using namespace std;typedef struct _LinkNode {	int value;	struct _LinkNode* next;} LinkNode, *LinkNodePtr;LinkNodePtr createCycle(int total) {	int index = 1;	LinkNodePtr head = NULL, curr = NULL, prev = NULL;	head = (LinkNodePtr) malloc(sizeof(LinkNode));	head->value = index;	prev = head;	while (--total > 0) {		curr = (LinkNodePtr) malloc(sizeof(LinkNode));		curr->value = ++index;		prev->next = curr;		prev = curr;	}	curr->next = head;	return head;}void run(int total, int tag) {	LinkNodePtr node = createCycle(total);	LinkNodePtr prev = NULL;	int start = 1;	int index = start;	while (node && node->next) {		if (index == tag) {			printf("%dn", node->value);			if (tag == start) {				prev = node->next;				node->next = NULL;				node = prev;			} else {				prev->next = node->next;				node->next = NULL;				node = prev->next;			}			index = start;		} else {			prev = node;			node = node->next;			index++;		}	}}int main() {        if (argc < 3) return -1;	run(atoi(argv), atoi(argv));	return 0;}

数学推导解法

我们将明确解出 k = 2 {displaystyle k=2} 是2的幂时,便重新从 f ( n ) = 1 {displaystyle f(n)=1} 、、……、 n / k {displaystyle lfloor n/krfloor } 个人视为一个步骤,然后把号码改变,可得如下递推公式, 运行时间为 O ( k log n ) {displaystyle O(klog n)}

程序实现(C++)

相关

  • 野生生物野生动物泛指各种生活在自然状态下,未经人类驯化的动物。自然界里,野生动物会用排泄物来标识其领土,宣示主权的习惯。野生动物,故名思意,为野外生长繁殖的动物,一般而言,具有以下特
  • Cmsub2/subOsub3/subCurium sesquioxide三氧化二锔是一种无机化合物,化学式为Cm2O3。锔能形成两种氧化物:三氧化二锔和二氧化锔(CmO2),其中前者更为常见。锔的氧化物都是固体,不溶于水但溶于无机酸。
  • 娄成后娄成后(1911年12月7日-2009年10月16日),天津人,祖籍浙江绍兴,中国植物生理学家。1932年获清华大学生物系理学士学位。1934年获岭南大学硕士学位。1939年获美国明尼苏达大学哲学博
  • 小农社会小农社会是经济学和经济史学者依照产业和社会结构所提出的一个概念。指社会上以分散的农民为主要的生产者的社会。“小农社会”与农业社会不同。
  • 丁鸿丁鸿(?-94年),字孝公,颍川郡定陵县(河南省郾城区西)人,东汉初期大臣。父亲丁�,随刘秀为偏将军,封陵阳侯。十三岁随桓荣学习欧阳尚书,明章句,善解经。父亲死后,让爵于弟,未获批准,教生徒。永平
  • 田所梓田所梓(1993年11月10日-)是日本的女性声优、歌手。从属于声优事务所HoriPro International、唱片公司Lantis。昵称主要使用“ころあず”。茨城县水户市出身。身高158cm,血型为AB
  • 大城卓三大城卓三(日语:大城 卓三/おおしろ たくみ ,1993年2月11日-)是一名出生于日本冲绳县那霸市的棒球选手,司职捕手,目前效力于日本职棒读卖巨人。74 村田善则 | 75 村田修一 | 77 元木
  • 东福间站东福间站(日语:東福間駅/ひがしふくまえき  */?)是位于福冈县福津市东福间一丁目,九州旅客铁道(JR九州)的鹿儿岛本线车站。车站编号为JA12。此站随着开始出售东福间团地住宅,车站
  • 火焰之纹章 暗黑龙与光之剑《火焰之纹章 暗黑龙与光之剑》(日版名:ファイアーエムブレム 暗黒竜と光の剣,英文版名:Fire Emblem: Shadow Dragon and the Blade of Light)是一款由Intelligent Systems及任天堂开发第一部共同开发、任天堂发行的战略角色扮演游戏,适用于红白机平台。这款游戏是火焰之纹章系列的第一款作品。游戏故事叙述邪恶祭司卡涅夫与暗黑龙梅迪乌斯联手重建多鲁亚帝国,并向周边国家展开侵略行动。主角马尔斯在祖国被帝国灭亡后成功逃离,为了复兴祖国,他必须联合其他志同道合
  • 明朝藩王列表 (荣王系)本页面列出明朝自明宪宗分封的荣国藩王。