约瑟夫环
2016-03-12 10:09
169 查看
要求:约瑟夫环的一种描述为:序号为1,2,...,n的n个人按顺时针方向围坐一圈,每个人持有一个密码(正整数),开始时任选一个数作为报数上限m,从第一个人开始顺时针自1开始顺序报数,报到m时停止报数,报的m的人出列,将他的密码作为新的m值,从他开始在顺时针方向的下一个人开始重新从1报数,如此下去,直至所有人全部出列,请设计一个程序,求出出列顺序。
如:当m的初始值为20,n=7,7个人的密码依次为:3,1,7,2,4,8,4,出列的顺序为6,1,4,7,2,3,5.思路:因为n个人围坐一圈,所以可以很自然的想到用单向循环链表作为存储结构来模拟此过程,然后按一定的条件删除某个结点,将该结点打印出来。
基于此思路代码如下:# include<stdio.h> # include<stdlib.h> # include<windows.h> typedef struct people { int order; int password; int nextorder; struct people * pnext; }p,*linklist; void main() { int n,m; printf("请输入人的个数n\n"); scanf("%d",&n); int count =0; int i=1; linklist phead=(linklist)malloc(sizeof(p)); linklist ptail=phead; while(count!=n)//构建约瑟夫环 { linklist pnew=(linklist)malloc(sizeof(p)); pnew->order=i; pnew->nextorder=i; printf("请输入该人的密码\n"); scanf("%d",&pnew->password); ptail->pnext=pnew; pnew->pnext=NULL; ptail=pnew; i++; count++; } ptail->pnext=phead; printf("请输入报数上限值m\n"); scanf("%d",&m); linklist ptemp=phead; linklist pre; // linklist ptemp=phead->pnext; int k=0; while(ptemp->pnext!=ptemp)//模拟出列过程 { pre=ptemp; ptemp=ptemp->pnext; if(ptemp==phead) { pre=ptemp; ptemp=ptemp->pnext; } k++; if(k==m) { printf("%d ",ptemp->order); m=ptemp->password; pre->pnext=ptemp->pnext; //linklist p=ptemp; free(ptemp); //ptemp=pre->pnext;不能这样写,因为头结点phead中无数据,如果是最后一个元素删除了则加1后ptemp到了phead, //k=1; 而phead中无数据所以多算了一步 ptemp=pre; k=0; } } }程序运行结果如下:
相关文章推荐
- 理解Android自定义的属性
- 约瑟夫环
- 如何删除一张表的重复记录
- poj 1988 多校联赛 带权并查集
- Fragment向activity传值的接口回调方法
- 写两个线程,一个线程打印 1~52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z
- c++中 vs 简单的对txt文件读写
- poj 1502MPI Maelstrom
- [LeetCode]232. Implement Queue using Stackssil
- Html5 手机wap开发、微信开发、APP开发的优缺点-创业者必知
- windows10 系统下为python配置numpy和scipy
- Samba 访问 Windows 7 共享 - tigertall - 博客园
- Mybatis 外部修改数据库形成的缓存问题
- 无法使用iotop怎么办
- 如何自己开发一款js或者jquery插件
- ACdream 1417 Numbers
- n!的近似值 (stirling approximation)与 大O记法(big -O- notation)
- 小学生四则运算
- bootstrap 水平导航 鼠标移动下拉,点击下拉。
- 【开源-Android】基于蓝牙备份联系人