• 用循环链表解决约瑟夫问题


    约瑟夫问题描述:
    从N个人中选出一个领导人,方法如下:所有人排除一个圆圈,按顺序数数,每数到第M的人出局,此时他两边的人
    靠拢重新形成圆圈,从已出局人的下一个继续进行。问题是找出哪一个人将会是最后剩下的那个人,甚至我们更希望
    知道出局人的顺序。

    算法思路:
    构造一个循环链表来表示排成圆圈的人。每人的链接指向圆圈内他左边(或者右边)的人。圆圈内人第i个人用整数i
    表示。首先为1号构造一个节点的循环链表,然后再把2~N号插入到1号节点之后,得到一个1~N的环,并时x指向节点N
    。然后从1号开始,跳过M-1个节点,把第M-1个节点的链接指向M+1号节点,即将第M个出局。继续这个过程,直到剩下
    一个节点为止。

    实现代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 typedef struct node* link;
     5 struct node {int item; link next;};
     6 
     7 int main(int argc, char *argv[])
     8 {
     9     int i, N=atoi(argv[1]), M=atoi(argv[2]);
    10     link t = malloc(sizeof *t), x = t;
    11     t->item = 1;
    12     t->next = t;
    13     for(i=2; i<=N; i++)
    14     {
    15         x->next = malloc(sizeof *x);
    16         x = x->next;
    17         x->item = i;
    18         x->next = t;
    19     }
    20     
    21     while(x != x->next)
    22     {
    23         for(i=1; i<M; i++) x = x->next;
    24         t = x->next;
    25         printf("%d
    ", t->item);
    26         x->next = t->next;
    27         free(t);
    28     }
    29     printf("The leader is:%d
    ", x->item);
    30     
    31     system("pause");
    32     return 0;
    33 }

    此代码参考了《算法:C语言实现(第1~4部分)》的程序3.9(p52),并做了一些修改。

    将代码在Dev C++中编译,并将参数设置为9 5(中间用空格隔开),即N为9,M为5,运行结果如下:

    5
    1
    7
    4
    3
    6
    9
    2
    The leader is:8
    请按任意键继续. . .

    特别的,如果将参数设置为9 1(中间用空格隔开),即N为9,M为1, 结果很容易想到,其如下:

    1
    2
    3
    4
    5
    6
    7
    8
    The leader is:9
    请按任意键继续. . .

     

    本文参考文献:《算法:C语言实现(第1~4部分)》,机械工业出版社,2011.8

  • 相关阅读:
    树形DP新识
    HDU3652 B-number 数位DP第二题
    HDU3555 Bomb 数位DP第一题
    数位DP新识
    Codeforces Round #371 & HihoCoder1529【玄学】
    hihocoder1618 单词接龙
    后缀数组 逐步探索
    HDU2157 How many ways矩阵再识
    阿里云安全中心:自动化安全闭环实现全方位默认安全防护
    趣谈预留实例券,一文搞懂云上省钱最新玩法
  • 原文地址:https://www.cnblogs.com/geekham/p/4104684.html
Copyright © 2020-2023  润新知