找回密码

碧海潮声大学生网

查看: 724|回复: 2
打印 上一主题 下一主题

哲学家就餐问题-C源码

[复制链接]
跳转到指定楼层
1#
发表于 2006-6-2 20:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
/*题目:一群哲学家围坐在一个圆桌,手上持有密码m,并从1开始编了号取初值m,哲学家从1开始报数, 报到m的哲学家停止吃饭,退出圆桌,求哲学家退出的顺序。要求:n和初值m由完家输入.手上的密码随机产生.最后要打印出编号对应的密码,输出哲学家离开的相后顺序

分析:可用循环链表实现,链表数据类型为结构体,记录编号和相应密码,另外设标志哲学家报数的变量mouth, 它的值和哲学家嘴上报的数相等,则如果mouth和m相等,该哲学家就应该离开离开前取他的密码交给m,同时将他的编号放另一单链表numbsave保存。注意编号要从numbsave的最后节点插入。当循环链表指向自身时停止比较,这个哲学家即是最后离开的一个.依次打印出numbsave中的数即为按编号哲学家离开的先后顺序。

*/            

#include "stdio.h"
#include "conio.h"
#include "stdlib.h"

struct philosopher        /*哲学家就餐结构体*/
{ int number;          /*编号*/
  int password;
  int mouth;    /*嘴上报的数*/
    struct  philosopher *next;
};
struct philosopher *phead,*pend,*pp;

struct numbsave              /*存放离开顺序*/
{ int numsave;
  struct numbsave *next;
};
struct numbsave *top=NULL,*numbnew,*numbthis;

void main(void)
{ char *p,d;
int  b=1,k,n,m,mouthm=1;
clrscr(); gotoxy(9,8);
printf("please input n m:");
scanf("%d%d",&n,&m);      /*n为哲学家人数,m为初始密码*/
phead=(struct philosopher *)malloc(sizeof(struct philosopher));
pend=phead;phead->mouth=1;
for(b=1;b<=n-1;b++)                      /*给哲学家分配随机密码*/
{pend->number=b;
  k=random(20);       /*k为0<k<20之间的数*/
  while(k<=0)
  k=random(20);
  pend->password=k;
  pp=(struct philosopher *)malloc(sizeof(struct philosopher));
  pend->next=pp; pend=pp;
}
pend->number=b;           /*最后一位哲学家*/
k=random(20); while(k<=0) k=random(20); pend->password=k; pend->next=phead; /*形成循环链表*/
printf("\n\tphilosopher number correspondence password as followed:\n\t");
pp=phead;
for(b=1;b<=n;b++)
{printf("%d:%d\t",pp->number,pp->password);
pp=pp->next;
}

while(pend->next!=pend)
{if(phead->mouth==m)               /*如果嘴上报数和m相等,意味着一个人要走了*/
  {pp=phead;
  phead->next->mouth=1; mouthm=1;  /*下一位哲学家从一开始报,mm用于将顺序报出数的交给嘴巴*/
  phead=pend->next=phead->next;   /*两个指针一定要相邻*/
  numbnew=(struct numbsave*)malloc(sizeof(struct numbsave));
  m=pp->password;           /*修改m的值为离开哲学家的password*/
  numbnew->numsave=pp->number;
  if(top==NULL) {top=numbnew; top->next=NULL;} /*离开的哲学家的编号存入numbsave的最后节点*/
  else  { numbthis=top;
  while(numbthis->next!=NULL)  numbthis=numbthis->next;
  numbthis->next=numbnew; numbnew->next=NULL;
  }
  free(pp);
  }
  else {pend=pend->next;
      phead=phead->next;         /*让phead指向下一个*/
      mouthm++;
      phead->mouth=mouthm;          /*嘴巴说我该报mouthm*/
      }
}     /*打印离桌顺序*/
printf("\n\tphilosopher away from cookdesk in the follow queue:\n\t");
while(top!=NULL)
{ printf("%d  ",top->numsave);
top=top->next;
}
printf("%d  ",pend->number);    /*这个千万别忘了,他是运气最好的一位*/
printf("\n\tpress any key to go back......");
while(!kbhit()) ;
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 顶 踩
2#
发表于 2006-6-8 03:10 | 只看该作者
Josephus Problem
简单!!!
3#
发表于 2006-6-10 16:47 | 只看该作者
上面的都是高手?  海院有高手?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋| 碧海潮声大学生网  

Copyright © 2001-2013 Comsenz Inc.   All Rights Reserved.

Powered by Discuz! X3.2( 浙ICP备11026473号 )

快速回复 返回顶部 返回列表