数据结构与算法分析 c++11 练习3.6 JosePhus 问题(Josephus problem)

来源:互联网 发布:北京下雨了 知乎 编辑:程序博客网 时间:2024/05/30 23:01


练习

  3.6 JosePhus 问题(Josephus problem)是下面的游戏:N个人编号1~N,围坐成一个圆圈。从1号人开始传递一个热土豆。经过M次传递后拿着热土豆的人被清除离座,围坐的圆圈锁紧,由坐在后面的人拿起热土豆继续进行游戏。最后剩下的人获胜。因此,如果M=0和N=5,则游戏人依序被清除,5号游戏人获胜。如果M=1 和N=5,那么被清除的人的顺序是2,4,1,5.

a. 编写一个程序解决在M和N为一般的值下的Josephus 问题,应使所编程序尽可能地高效率,要确保各个单元都能被清除。

b. 这个程序的运行时间是多少?

c. 如果M=1,这个程序的运行时间又是多少? 对于N的一些大值(N>100000), delete 例程如何影响该程序的速度?


          解答: 执行1000次,需要1.26 秒。


#include <iostream>#include <chrono>     // 求运行时间的库using namespace std;using namespace chrono;typedef struct LNode{int data;struct LNode *link;LNode(){data = 0;link = NULL;}}LNode,*LinkList;/**  n 为总人数 *  k 为第一个开始传递的人*  m 为拿到土豆被剔除的人*/int Josephus(int n, int k, int m){// pnode 为当前节点,prenode 为辅助节点,指向pnode 的前驱节点,curr 为头结点if(n < 0 || k < 0 || m < 0)return -1;LinkList pnode, prenode, curr;pnode = new LNode();pnode->data = 1;pnode->link = pnode;            //建立循环链表curr = pnode;for (int i = 2; i <= n; i++) {LinkList temp = new LNode();temp->data = i;temp->link = curr->link;curr->link = temp;curr = temp;}prenode = curr;while (k--) {prenode = pnode;       //prenode 是pnode的前一个节点pnode = pnode->link;   //移动节点pnode 到第k个元素开始}while (n>1){// for 是移动m个位置,pnode会移动到m的位置,prenode 是pnode 的前一个节点for (int s = m; s>0;--s){prenode = pnode;pnode = pnode->link;}prenode->link = pnode->link;                     //删除pnode节点cout << "deleted node is " << pnode->data << endl;free(pnode);                              //释放空间pnode = prenode->link;                     // 从prenode 的下一个节点开始,数一个m个节点的值n--;}return pnode->data;}int main(){//k=0,表示从第一个人开始,m表示每次移动m个人//josePhus(5, 0, 1);int winner;auto start = system_clock::now();for(size_t i=0;i<1000;++i)   winner=Josephus(5,0,1);auto end = system_clock::now();auto duration = duration_cast<microseconds>(end - start);cout << " Consume:  " << double(duration.count())*microseconds::period::num / microseconds::period::den << " s(秒)" << endl;cout <<"The winner is "<< winner << endl;return 0;}


0 0
原创粉丝点击