约瑟夫环

原创 2007年09月23日 01:01:00

问题描述:

编号为1,2,……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他的顺时针方向上的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。设计一个程序求出出列顺序。

基本要求:

利用单项循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。

测试数据:

m的初始值为20;n=7,7个人的密码依次为:3,1,7,2,4,8,4,首先m值为6(正确的出列顺序为:6,1,4,7,2,3,5)。

代码:

// Child.h
struct Child {
  int id;   // 编号
  int passwd; // 密码
};
// Node.h
#include "Child.h"
struct Node {
  Child* child;
  Node* next;
};
// CircleLinkList.h
#include "Node.h"
class CircleLinkList {
public:
  CircleLinkList();
  void append(Child* child);
  Child* remove(int index);
  bool isEmpty();
  ~CircleLinkList();
private:
  Node* rear; // 尾指针
  int length;
};
// CircleLinkList.cpp
#include "CircleLinkList.h"
CircleLinkList::CircleLinkList() {
  rear = 0;
  length = 0;
}
void CircleLinkList::append(Child *child) {
  Node* n = new Node;
  n->child = child;
  if (!rear) n->next = n;
  else {
   n->next = rear->next;
   rear->next = n;
  }
  rear = n;
  ++length;
}
Child* CircleLinkList::remove(int index) {
  Node* p = rear;
  Node* f = 0;
  for (int i = -1; i < index % length - 1; ++i)
   p = p->next;
  if (p->next == p) {
   f = p;
   rear = 0;
  }
  else {
   f = p->next;
   p->next = p->next->next;
   if (p != rear)
    rear = p;
  }
  Child* child = f->child;
  delete f;
  --length;
  return child;
}
bool CircleLinkList::isEmpty() {
  return rear == 0;
}
CircleLinkList::~CircleLinkList() {}
// main.cpp
#include "CircleLinkList.h"
#include <iostream>
int main() {
  using namespace std;
  CircleLinkList l;
  cout << "Please input the password of each child by order:" << endl;
  int id = 1;
  int passwd;
  while (cin >> passwd) {
   Child* c = new Child();
   c->id = id;
   c->passwd = passwd;
   l.append(c);
   ++id;
  }
  int m = 20;
  while (!l.isEmpty()) {
   Child* c = l.remove(m - 1);
   id = c->id;
   m = c->passwd;
   delete c;
   cout << id;
   if (!l.isEmpty()) cout << ", ";
  }
  cout << endl;
  return 0;
}

约瑟夫环的链表解法和数学解法

约瑟夫环(Josephus)问题是由古罗马的史学家约瑟夫(Josephus)提出的,他参加并记录了公元66—70年犹太人反抗罗马的起义。约瑟夫作为一个将军,设法守住了裘达伯特城达47天之久,在城市沦陷...
  • haishu_zheng
  • haishu_zheng
  • 2013年12月09日 11:42
  • 14179

10行Python代码解决约瑟夫环(模拟)

写这篇文章是因为看到别人博客里用了很长一个篇幅(超过50行)去解决一个约瑟夫环问题,而且还是用以简洁著称的python,另外,如果你用X度搜索python 约瑟夫,看到得前几条都是错的,真是好悲剧。 ...
  • u011044759
  • u011044759
  • 2014年09月11日 17:21
  • 30615

约瑟夫环 python 实现

面试的过程中遇到了这个问题。就是经典的约瑟夫环。
  • u012250655
  • u012250655
  • 2014年07月28日 00:43
  • 1717

Java实现约瑟夫环问题

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;...
  • qq_21150865
  • qq_21150865
  • 2017年03月05日 14:48
  • 4489

史上最全的约瑟夫环算法程序和原理

数学算法:#include "stdio.h"#include "stdlib.h"int josephus(int n, int m){    int pos;    if (n == 1) {  ...
  • ZhengKarl
  • ZhengKarl
  • 2010年05月15日 21:47
  • 32573

最简化约瑟夫环问题的递归算法详细解析

这个问题可能每个学算法的同学都会遇见,我没那么聪明,第一次看见时做不出来,只发现一些规律,后面看到算法也挺久才看懂,这里是将别人的算法结果做一个解析,例子是暂时网上找的递归最简洁的例子: 下面就以这个...
  • m15682532244
  • m15682532244
  • 2017年10月21日 15:54
  • 302

约瑟夫环的数组实现

 #includevoid main(){ const int tNum=10;//10个小孩 int a[tNum];//放小孩编号的数组,模拟小孩 int interval,num=10; cou...
  • XHWWL
  • XHWWL
  • 2008年02月26日 20:47
  • 622

数据结构(二)java解决约瑟夫环的两种方法

使用组数解决约瑟夫环问题 使用队列解决约瑟夫环问题
  • shuaicihai
  • shuaicihai
  • 2017年02月03日 15:48
  • 2269

两种方法实现约瑟夫环(链表,顺序表)

//两种方法解决约瑟夫问题:顺序存储结构,循环单链表, //测试数据:a,b,c,d,e,f,g,h,i,j,n=10;从第2个开始,数到5即:s=2,m=5 //结果f,a,g,c,j,i,b,e,...
  • TFLiu666
  • TFLiu666
  • 2017年03月27日 20:58
  • 540

PHP篇之二个函数解决约瑟夫环问题

讲故事了! 约瑟夫环问题起源于一个犹太故事。:   罗马人攻占了桥塔帕特,41个人藏在一个山洞中躲过了这场浩劫。这41个人中,包括历史学家Josephus(约瑟夫)和他的一个朋友。剩余的39个人为...
  • backOrigin
  • backOrigin
  • 2016年12月17日 23:14
  • 991
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:约瑟夫环
举报原因:
原因补充:

(最多只允许输入30个字)