我真是大明星完本了吗:急求Josephu 问题解决方案

来源:百度文库 编辑:中科新闻网 时间:2024/04/29 07:01:49
Josephu 问题为:设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

提示:用一个不带头结点的循环链表来处理Josephu 问题,先构成一个有n个结点的单循环链表,然后由k结点起从1开始计数,记到m时,对应结点丛链表中删除,然后被删除的结点得下一个结点又从1开始记数,直到最后一个结点丛链表中删除,算法结束。

要求:用C语言编写程序 在TC下运行。
输出格式:每10个一行,信息描述、结构清晰。
n由用户输出,报数的上限m由用户输出。
是否进行查询由用户自行选择;每次一个相对完整的操作结束后 是否继续执行程序由用户自己选择。

#include <stdio.h>
#include <malloc.h>
#include <memory.h>
//pLeft长度固定为N, 表示队伍中留下人的位置.nLeave是离开的人数, 判断结束
//输出是依次从队伍中离开的人的序号.
int fun(unsigned char *pLeft, int N, int *nLeave, int m, int nStart)
{
int nCount=0,nPoint=nStart;
if(pLeft[nPoint]==1)
nCount++;
while(nCount<m)
{
nPoint=nPoint%N+1;
if(pLeft[nPoint]==1)
nCount++;
}
(*nLeave)++;
pLeft[nPoint]=0;
return nPoint;
}

void main(int argc, char *argv[])
{
int n=0,m=0,nLeave=0,nStart=1;
printf("输入 人数n,上限m.\n");
scanf("%d,%d",&n,&m);
unsigned char *pLeft=(unsigned char *)calloc(n+1,sizeof(char));
memset(pLeft,1,(n+1)*sizeof(char));
while(nLeave<n)
printf("%d\t",nStart=fun(pLeft, n, &nLeave, m, nStart));
free(pLeft);
}

---------输出,20个人,m=26------------
输入 人数n,上限m.
20,26
6 13 1 11 3 17 14 12 16 2
10 8 15 5 9 18 20 7 4 19