古老而简单的约瑟夫问题

天大地大妈咪最大 提交于 2019-12-26 04:45:48

约瑟夫问题的传说:

        著名犹太历史学家 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 }

运行结果:

                   

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

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!