约瑟夫问题的传说:
著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。然而Josephus 和他的朋友并不想遵从,Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
抽象出来问题分析与算法设计:
已知n个人(以编号1、2、3~~n分别表示)围坐在一张圆桌周围,从编号为k的人开始报数,数到m的那个人出列,他的下一个人又从1开始报数,数到m的那个人出列,依次规律重复下去,直到圆桌周围的人全部出列。
例如:n = 9, k = 1, m = 5
【解答】
出局人的顺序为5, 1, 7, 4, 3, 6, 9, 2, 8。
程序代码:
很明显这个问题用循环连接即可解决。
1 #include <iostream>
2 using namespace std;
3
4 //定义节点结构体
5 struct node{
6 int data;
7 struct node *link;
8 };
9
10 void Josephus(int n, int k, int m);
11
12 int main()
13 {
14 int n, k, m;
15 cout << "please input the parameters of Josehpus (n, k, m):";
16 while(cin >> n >> k >> m)
17 {
18 Josephus(n, k, m);
19 cout << "please input the parameters of Josehpus (n, k, m):";
20 }
21 return 0;
22 }
23
24 void Josephus(int n, int k, int m)
25 {
26 //定义头结点
27 cout << "creat the node: ";
28 node *current, *temp, *head;
29 temp = new node;
30 temp->data = 1;
31 temp->link = temp;
32 current = head = temp;
33 cout << temp->data << " ";
34
35 //建立循环链表
36 for(int i = 2; i <= n; ++i)
37 {
38 temp = new node;
39 temp->data = i;
40 temp->link = current->link;
41 current->link = temp;
42 current = temp;
43 cout << temp->data << " ";
44 }
45 node *previous = current;
46 current = head;
47
48 //是当前指针定位到第k个人
49 while(--k)
50 {
51 previous = current;
52 current = current->link;
53 }
54
55 cout << endl << "the list of deleting node:";
56
57 while(n--)
58 {
59 //指针移动至第m个人
60 for(int i = 1; i < m; ++i)
61 {
62 previous = current;
63 current = current->link;
64 }
65
66 //删除操作
67 previous->link = current->link;
68 cout << current->data << " ";
69 delete current;
70 current = previous->link;
71 }
72
73 cout << endl;
74 }
运行结果:

已有很长一段时间没上博客园了,由于寝室有个同学天天和我炫耀他在博客园的排名节节高升,于是又激起了写技术博客的冲动,这是一个纯粹的平台,只有技术上的烦恼和困惑,但总能在上面找到答案。前几天帮一个大学的小师弟讲了个约瑟夫的问题,就当留作纪念吧!
来源:https://www.cnblogs.com/phquan/archive/2012/11/02/2751818.html