约瑟夫环问题
来源:互联网 发布:联赢激光怎么样 知乎 编辑:程序博客网 时间:2024/05/09 08:15
简介
约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。
编程解决思路
思路一 环形链表
很显然立马就会联想到用环形链表解决,很直观,编码也不会很难,控制好环形链表的头尾指针就好。(默认1号开始报数,可以添加参数K)
代码:
//链表解决,定义人结构体(链表节点)struct people{ int id; struct people* next;};//n为人数,m为报号数字void Joseph(int n,int m){ int i ,j,no=0; struct people first ; //建立第一个人 struct people* ring_head =&first; struct people* ring_tail =&first; struct people* pring =&first; struct people* p_new =NULL; first.id = 1; //第一个人编号 for (i=2;i<=n;i++) //再创建剩下的N-1个人 { struct people* p_new = (struct people*)malloc(sizeof(struct people)); p_new->id = i; pring->next = p_new; pring = p_new; } //构成环状链表 pring->next = ring_head; //最后一个人的next 指向第一个人 ring_tail = pring; //尾指针指向最后一个人 //当还剩一个人时结束循环,否则一直按规则报数 while(ring_head!=ring_tail) { no++;//轮次 for(i=1;i<m;i++) { ring_head = ring_head->next; //下一个人继续报数 ring_tail = ring_tail->next; //尾指针也要跟着移动 } printf("现在是第%d次报数,我是第%d号同学,现在报到了%d号,退出游戏!",no,ring_head->id,m); printf("\n"); //删除退出游戏的节点 ring_head = ring_head->next; ring_tail->next = ring_head; } printf("现在是第%d次报数,我编号为%d,是最后一个同学,游戏结束!",no+1,ring_head->id,m); printf("\n");}
思路二 数学推导递归解决
假设下标从0开始,0,1,2 .. m-1共m个人,从1开始报数,报到k则此人从环出退出,问最后剩下的一个人的编号是多少?
现在假设m=10
0 1 2 3 4 5 6 7 8 9 k=3
第一个人出列后的序列为:
0 1 3 4 5 6 7 8 9
即:
3 4 5 6 7 8 9 0 1(*)
我们把该式转化为:
0 1 2 3 4 5 6 7 8 (**)
则你会发现: ((*)+3)%10则转化为()式了
也就是说,我们求出9个人中第9次出环的编号,最后进行上面的转换就能得到10个人第10次出环的编号了
设f(m,k,i)为m个人的环,报数为k,第i个人出环的编号,则f(10,3,10)是我们要的结果
当i=1时, f(m,k,i) = (m+k-1)%m
当i!=1时, f(m,k,i)= ( f(m-1,k,i-1)+k )%m
代码:
//约瑟夫环 (递归解决)int Joseph_r(int n,int m,int i){ if (i==1) { return (n+m-1)%n; } else { return (Joseph_r(n-1,m,i-1)+m)%n; }}
测试代码 & 运行结果
//主函数中测试代码 //递归 for(i=1;i<=10;i++) printf("第%2d次出环:%2d\n",i,Joseph_r(10,3,i)+1); //环链 Joseph(10,3);
运行结果:
0 0
- 约瑟夫问题、约瑟夫环
- Josephus约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题(Josephus)
- 约瑟夫环问题--java
- 约瑟夫环问题 Josephus
- 约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题
- 求解约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题
- 约瑟夫环问题
- 视频网站基于srs的直播业务压力测试
- ACM今日学习总结(2015.07.28)
- Web前端优化
- Gym 100513F - Ilya Muromets
- 法规和国际化法国红酒
- 约瑟夫环问题
- C++基础---整型
- Javascript笔记总结
- Spark进阶视频之Scala界面Panel、Layout实战详解
- ZOJ1008(深搜)
- HDU 2601 An easy problem(暴力枚举/质因子分解)
- Gym 100513I - Sale in GameStore
- 把握linux内核设计思想(五):下半部机制之工作队列及几种机制的选择
- ListView