博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ 用循环链表解决约瑟夫环问题
阅读量:4708 次
发布时间:2019-06-10

本文共 2794 字,大约阅读时间需要 9 分钟。

约瑟夫环问题

    已知 n 个人(n>=1)围坐一圆桌周围,从 1 开始顺序编号,从序号为 1 的人开始报数,顺时针数到 m 的那个人出列。下一个人又从 1 开始报数,数到m 的那个人又出列。依此规则重复下去,直到所有人全部出列。请问最后一个出列的人的初始编号。

 

要求

    输入人数 n,所报数 m,输出最后一个人的初始编号。

 

解决思路

  • 首先因为是圆桌问题,使用链表解决的话需要构建循环链表。
  • 接着是出列问题,这里我的设计思路是将指向链表的指针移动到需要出列的人的位置,然后根据正常的链表删除进行操作即可。
  • 最后是类的设计,可以将 head 、 m、 n、链表构建、链表删除等整合到一起进行封装。

 

代码

1 // 6.cpp -- using gcc compiler   2 #include 
3 using namespace std; 4 5 typedef struct List 6 { 7 int num; 8 struct List *next; 9 }*pList; 10 11 class Josephus 12 { 13 public: 14 Josephus() {} 15 Josephus(int number, int mes): 16 n(number), 17 m(mes){} 18 void set(); 19 void creat(); 20 void del(); 21 private: 22 pList head; 23 int n, m, tmp_n; 24 }; 25 26 void Josephus::set() 27 { 28 cout << "please input the number of the people: "; 29 cin >> n; 30 tmp_n = n; 31 cout << "please input the m: "; 32 cin >> m; 33 } 34 35 void Josephus::creat() 36 { 37 pList p1, p2; 38 pList p = new List; 39 n += 1; 40 p -> num = 1; 41 p2 = head = p; 42 for(int i = 2; i < n; i++) 43 { 44 p = new List; 45 p -> num = i; 46 47 p1 = p2; 48 p2 = p; 49 p1 -> next = p2; 50 } 51 52 p2 -> next = head; 53 // output each number of the circle list's members. 54 // and it should be: 1, 2, ..., n 55 p = head; 56 cout << "Now, the \"num\" member of the list is: " << endl; 57 while(n--) 58 { 59 if(n == 0) 60 cout << p-> num << "."; 61 else 62 { 63 cout << p->num << ", "; 64 p = p -> next; 65 } 66 } 67 } 68 69 void Josephus::del() 70 { 71 pList p1 = NULL; 72 pList p2 = head; 73 74 n = tmp_n + 1; 75 while(n--) 76 { 77 int s = m - 1; 78 while(s--) 79 { 80 p1 = p2; 81 p2 = p2 -> next; 82 } 83 84 if(n == 0) 85 { 86 p2 = p2 -> next; 87 p1 -> next = NULL; 88 cout << "The result is: " << p2 -> num << endl; 89 } 90 else 91 { 92 p2 = p2 -> next; 93 p1 -> next = p2; 94 } 95 } 96 } 97 98 int main() 99 {100 Josephus t;101 t.set();102 t.creat();103 cout << endl;104 t.del();105 return 0;106 }

 

代码解析

    5-9行定义了链表的结构,其中 num就是初始编号

    23行的 tmp_n 负责记录 n 的初始值

    75行开始进行循环,共循环 n+1 次,每次都将 p2 移动到需要被排除的人的位置。

    n=0时为最后一次循环,此时p1、p2都指向最后一个人,输出 num。

    n!=0则去掉p2指向的节点,开始下一次循环。

 

解决约瑟夫环问题的关键在于去掉计数为 m 的那个人,并从他之后开始重新计数。

而以上的解决方案巧妙的利用了循环链表来解决问题。因为对链表的了解不算深入,所以暂时还想不出更好的解决方案。

 

总结

解决链表问题的关键在于对链表的构建以及其他操作,而链表的问题只靠想象是不可能的解决的,最好还是自己动手画图,这样一切都会变得清晰明了,问题也会迎刃而解。

转载于:https://www.cnblogs.com/AlexMiller/p/5532422.html

你可能感兴趣的文章
body用渐变图片作背景
查看>>
字符串题表
查看>>
Application windows are expected to have a root view controller at the end of application launch
查看>>
归并排序
查看>>
Deep RL Bootcamp Lecture 3: Deep Q-Networks
查看>>
Vue引入jQuery
查看>>
Intellij IDEA 像eclipse那样给maven添加依赖
查看>>
网页截图像素与实际像素不一致问题
查看>>
QT容器map的插入,修改,遍历
查看>>
递归算法--写实例----阶乘问题---整数划分问题
查看>>
hibernate分表保存日志
查看>>
Java实现文件上传
查看>>
【IBM-WALA】Step by Step : use WALA to generate System Dependency Graph PDF and Dot File (Mac)
查看>>
[AHOI2005] SHUFFLE 洗牌
查看>>
拆迁管理系统--分割字符串的函数
查看>>
ZOJ1360 POJ1328 Radar Installation, 贪心
查看>>
poj1191 棋盘分割。 dp
查看>>
Python函数
查看>>
C++实现网格水印之调试笔记(五)—— 提取出错
查看>>
SpringMVC导出Excel
查看>>