鱼C论坛

 找回密码
 立即注册
查看: 4750|回复: 10

一道习题,求解题的思路.

[复制链接]
发表于 2013-3-30 17:58:30 | 显示全部楼层 |阅读模式
10鱼币
本帖最后由 Whisper微风 于 2013-4-1 13:35 编辑

题目如下: 一个旅行社 要从n个旅客中选出一位旅客,为他提供免费的环球旅行服务.旅行社安排这些旅客围成一个圆圈,从帽子中取出一张纸条,用上面的写正整数 m(m<n)作为报数值.游戏进行时,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数,报m的人被淘汰出列,然后从他顺时针方向上的下一个人开始重新报数,如此下去,知道圆圈中只剩下一个人,这个最后的幸存者就是游戏的胜利者,将得到免费旅行的奖励.

流程图 也可 .非常感谢.

最佳答案

查看完整内容

只要使用循环的线性表,都可以按游戏描述简单的实现这个问题。这是我使用循环链表写的代码。
小甲鱼最新课程 -> https://ilovefishc.com
发表于 2013-3-30 17:58:31 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. #define N 10        // 旅客数
  4. #define M 4                // m

  5. typedef struct _Node {
  6.         int num;

  7.         struct _Node *next;
  8. } Node, *PNode, *Ring;

  9. bool InitRing(Ring &r) {
  10.         PNode pr = NULL;
  11.         for (int i = 0; i < N; ++i) {
  12.                 // 创建节点
  13.                 PNode p = (PNode)malloc(sizeof(Node));
  14.                 if (!p) return false;

  15.                 if (0 == i) {        // 第一个节点为首节点
  16.                         pr = r = p;
  17.                 } else {                // 节点加入链表
  18.                         pr->next = p;
  19.                         pr = pr->next;
  20.                 }

  21.                 p->num = i + 1;        // 旅客编号
  22.                 p->next = r;        // 形成循环链表
  23.         }

  24.         return true;
  25. }

  26. bool DestroyRing(Ring r) {
  27.         if (!r) return false;

  28.         PNode pdel = r;
  29.         PNode pr = NULL;
  30.         do {
  31.                 pr = pdel->next;        // 需删除节点的下一个节点
  32.                 free(pdel);                        // 删除节点
  33.                 pdel = pr;
  34.         } while (pr != r);        // 已删除节点的下一节点若为r,则节点删除完毕

  35.         return true;
  36. }

  37. int GamePlaying(Ring &r) {
  38.         PNode pr = r;
  39.         PNode pdel = r;
  40.         while (pr != pr->next) { // 只有一个节点时,退出循环
  41.                 // 找到淘汰者
  42.                 for (int i = 0; i < M - 1; ++i) {
  43.                         pr = pdel;
  44.                         pdel = pdel->next;
  45.                         printf("%d\n", pr->num);
  46.                 }
  47.                 pr->next = pdel->next;
  48.                 free(pdel);        // 删除淘汰者节点
  49.                 pdel = pr->next;
  50.         }

  51.         r = pr;
  52.         return r->num;
  53. }

  54. int main(int argc, char *argv[]) {
  55.         Ring JosephRing = NULL;
  56.         InitRing(JosephRing);

  57.         int pnum = GamePlaying(JosephRing);
  58.         printf("Game Winner:%4d\n", pnum);

  59.         DestroyRing(JosephRing);

  60.         return 0;
  61. }
复制代码
只要使用循环的线性表,都可以按游戏描述简单的实现这个问题。这是我使用循环链表写的代码。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-30 18:06:47 | 显示全部楼层
用循环队列可以不?用一个循环判断队列是否只剩下一个元素。最后打印该元素~~
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-30 20:55:55 | 显示全部楼层
甲鱼的数据结构视频中,讲了一道这样的题
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-30 20:56:52 | 显示全部楼层
记得甲鱼的数据结构视频中,讲了一道这样的题
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-31 09:46:36 | 显示全部楼层
要求有点高,网上应该有源码吧。自己下去
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-31 10:03:45 | 显示全部楼层
一、数组模拟
二、数学公式
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-3-31 13:17:01 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int paixu ( int *, int , int ,int ,int *, int * );
  4. int blSZ ( int * ,int  );


  5. int main(int argc, char *argv[])
  6. {       
  7.         int i,n,m;
  8.         printf("输入人数和随机数\n");
  9.         scanf ( "%d %d",&n,&m );
  10.         if (m>n)
  11.         {
  12.                 printf("输入错误.\n");
  13.                 system ("Pause");
  14.                 return 0 ;
  15.         }
  16.         int a[n];
  17.         for ( i=0 ;        i<n ;i++ )  //数组置1 ,淘汰则被置 0;
  18.         {
  19.                 a[i]= 1;
  20.         }
  21.         paixu ( a , n, m ,0,  a, a);
  22.         for ( i=0 ;        i<n ;i++ )   
  23.         {
  24.                 printf("a[%d]=%d \n",i,a[i]);
  25.         }
  26.         system ( "Pause" );
  27.         return 0;
  28. }





  29. int paixu ( int *P ,int N , int M ,int iJishu, int *iWeizhi,int *iChaxun )
  30. {
  31.         if (blSZ( P,N )==1)
  32.         {
  33.                 return ;
  34.         }
  35.         else
  36.         {
  37.                 // iChaxun指向最后一个数组元素时的处理.
  38.                 if (iChaxun-P==N)
  39.                         {
  40.                         if (iJishu<M)
  41.                                 {
  42.                                         if (*iChaxun==0)
  43.                                         {
  44.                                                 iChaxun=P;
  45.                                         }
  46.                                         if (*iChaxun==1)
  47.                                         {
  48.                                                 iJishu++;
  49.                                         }
  50.                                 }
  51.            if (iJishu==M)
  52.                         {
  53.                                 *iChaxun=0;
  54.                                  iJishu=0;
  55.                         }
  56.                         //查询起始数组元素位于数组尾时
  57.                         if (iWeizhi-P==N)
  58.                         {
  59.                                 iWeizhi=P;
  60.                                 iChaxun=iWeizhi;
  61.                         }
  62.                         else
  63.                         {
  64.                                 iChaxun=P;
  65.                         }
  66.         }
  67. /////////////////////////////////////////////
  68.    // 计数 查询 置 0
  69.         if (iChaxun-P<N)
  70.                 {
  71.                         if (*iChaxun==0)
  72.                         {
  73.                                 iChaxun++;
  74.                         }
  75.                         if (*iChaxun==1)
  76.                         {
  77.                                 iJishu++;
  78.                                 if (iJishu==M)
  79.                                 {
  80.                                         iJishu=0;
  81.                                         iWeizhi ++;
  82.                                         *iChaxun=0;
  83.                                         iChaxun=iWeizhi;
  84.                                 }
  85.                                 if (iJishu<M)
  86.                                 {
  87.                                         iChaxun ++;
  88.                                 }
  89.                
  90.                         }
  91.                 }
  92.         }
  93.         return paixu(P, N , M, iJishu ,iWeizhi , iChaxun );
  94. }


  95. int blSZ ( int *sz ,int n )
  96. {
  97.         int i;
  98.         int temp=0 ;
  99.         for ( i=0 ; i<n ; i++ ) //遍历数组,查看值是否为1,是否只剩下一个人 ;
  100.         {
  101.                 temp += *sz++ ;
  102.                  
  103.         }

  104.         if (temp==1)
  105.         {
  106.                 return 1;
  107.         }
  108.         else
  109.         {
  110.                 return 0;
  111.         }
  112. }


复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-3-31 13:18:31 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2013-3-31 19:09:02 | 显示全部楼层
坦_然 发表于 2013-3-31 13:18
用什么数学公式,能否介绍下.谢谢.

百度约瑟夫环问题 百度百科里就有

评分

参与人数 1鱼币 +5 贡献 +5 收起 理由
坦_然 + 5 + 5 感谢,热心帮助.

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-3-31 21:53:15 | 显示全部楼层
故乡的风 发表于 2013-3-30 17:58
只要使用循环的线性表,都可以按游戏描述简单的实现这个问题。这是我使用循环链表写的代码。

不太懂,复制保存,留作日后学习.谢谢你的解答.你的付出,我们为之努力.
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-13 12:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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