约瑟夫问题-Josephus--及实例说明
2016-08-25 19:44
344 查看
类似约瑟夫的问题又称为约瑟夫环。又称“丢手绢问题”。
这个问题来自于这样的一个关于著名犹太历史学家 Josephus传说: 在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
约瑟夫问题是个有名的问题,比如6个人围一个圈,从第一个人开始123123的报数,最后一个报完了循环到第一个继续报数,报到数字3的人就退出游戏。这样退出的顺序就是: 3 6 4 2 5,最后剩下1一个人。
解决问题:
就像题中描述的一样直接翻译成代码是(拯救约瑟夫的代码):
View Code
主要是练习双向链表的结构而已,原理和单向循环链表类似。
⑦、其实还有队列也可以实现,不过利用队列实现和方法③的思想就相似了,有想法的初学者小码友可以自己去操作一下。
先总结这些,再有灵感再往上面加.欢迎批评。
这个问题来自于这样的一个关于著名犹太历史学家 Josephus传说: 在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从。首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。接着,再越过k-1个人,并杀掉第k个人。这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。问题是,给定了和,一开始要站在什么地方才能避免被处决?Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
约瑟夫问题是个有名的问题,比如6个人围一个圈,从第一个人开始123123的报数,最后一个报完了循环到第一个继续报数,报到数字3的人就退出游戏。这样退出的顺序就是: 3 6 4 2 5,最后剩下1一个人。
解决问题:
就像题中描述的一样直接翻译成代码是(拯救约瑟夫的代码):
#include <stdio.h> #include <malloc.h> #include <stdlib.h> struct node { int data; struct node *prior, *next; }; struct node *creat (int n, struct node *h) { h = NULL; struct node *s, *q; for (int i = 1; i <= n; ++i) { s = (struct node *)malloc(sizeof (struct node)); s->data = i; s->next = NULL; if (h == NULL) { h = s; s->prior = h; s->next = h; } else { s->next = q->next; q->next = s; s->prior = q; h->prior = s; } q = s; } return h; } struct node *work (struct node *head, int m) { struct node *p, *q; p = head; while (p->next != p) { for (int i = 1;i < m; ++i) { q = p; p = p->next; } q->next = p->next; p->next->prior = q; printf ("%4d ", p->data); free (p); p = q->next; } return p; } int main () { int m, n; //n代表一共有n只猴子, m表示循环次数. scanf ("%d%d", &n, &m); struct node *head; head = creat(n, head); printf ("被删除的节点是:\n"); printf ("\n新大王是:%4d\n", work(head, m)->data); return 0; }
View Code
主要是练习双向链表的结构而已,原理和单向循环链表类似。
⑦、其实还有队列也可以实现,不过利用队列实现和方法③的思想就相似了,有想法的初学者小码友可以自己去操作一下。
先总结这些,再有灵感再往上面加.欢迎批评。
相关文章推荐
- 约瑟夫问题(Josephus)
- Access转Sql Server问题 实例说明
- Josephus problem(约瑟夫问题)
- 约瑟夫问题(Josephus Problem)4:第k个出列的人是谁
- 约瑟夫问题(Josephus Problem)3:谁最后一个出列
- 几个可运行的,可以说明问题的Ajax实例
- java数组解决约瑟夫(Josephus)问题
- Josephus(约瑟夫)问题----分别用循环链表和数组实现
- 约瑟夫(Josephus)问题
- josephus problem——约瑟夫问题
- 约瑟夫问题(Josephus Problem)
- Josephus 约瑟夫 问题
- 约瑟夫问题(Josephus问题)的递推O(n)解法、循环解法、单循环链表解法
- 3.java类特征(Josephus约瑟夫问题)
- Josephus(约瑟夫)问题
- 实例说明PHPLOT中的绘制汉字标题问题
- 【待解惑问题(已解决)】约瑟夫(Josephus)环问题
- 约瑟夫问题(Josephus)java链表解决
- C语言通过双向循环链表解决Josephus(约瑟夫)问题
- 约瑟夫(环)问题(Josephus problem)