• 算法12---约瑟夫环问题


    算法12---约瑟夫环问题

    1 首先我们来解决一个约瑟夫环的问题,再慢慢的深入。
     
    问题描述:
    罗马人攻占了桥塔帕克,41个人躲在一个山洞中,逃过了这场浩劫。这41人中,包括历史学家约瑟夫和他的一个朋友。剩余的39人为了表示不想屈服罗马人,决定集体自杀。大家想到了一个自杀方案,这41个人围城一个圆圈,由第一个人开始顺时针报数,每报数为3的人就立刻自杀。然后再由下一个人重新开始报数,仍然是每报数为3的人自杀,。。。。,直到所有的人都自杀身亡;
    约瑟夫和他的朋友不想自杀,于是约瑟夫想到了一个计策,他们两个同样的参与到自杀方案中,但是最后却躲过了自杀,请问,他是怎么做到的?
     
     1 #include <String.h>
     2 #include <stdio.h>
     3 #include <malloc.h>
     4 
     5 
     6 #define Num 41
     7 #define killman 3
     8 
     9 void josephus(int alive)
    10 {
    11     int man[Num]={0};
    12     int count=1;
    13     int i=0;
    14     int pos=-1;
    15     while(count<=Num)
    16     {
    17         do
    18         {
    19             pos=(pos+1)%Num;//环处理
    20             if (man[pos]==0)
    21             {
    22                 i++;
    23             }
    24             if (i==killman)
    25             {
    26                 i=0;
    27                 break;
    28             }   
    29         }while(1);
    30         man[pos]=count;
    31         printf("the %2d people die! the number of josephus is %2d
    ",pos+1,man[pos]);
    32 
    33         count++;
    34     }
    35     printf("the %d man who want to live should be in the number of :
    ",alive );
    36     alive=Num-alive;
    37     for (int i = 0; i < Num; i++)
    38     {
    39         if (man[i]>alive)
    40         {
    41             printf("init number:%d.josephus number:%d
    ",i+1,man[i]);
    42         }
    43     }
    44     printf("
    ");
    45 }
    46 
    47 
    48 int  main()
    49 {
    50     int alive;
    51     printf("the solve of josephus!
    ");
    52     printf("the number fo people want to live:");
    53     scanf("%d",&alive);
    54     josephus(alive);
    55     return 0;
    56 }
     
     
    2 我们就上面的问题引出josephus排序问题;
    就是对任意输入的人数,决定自杀的个数,输出自杀的顺序;
     
     1 #include <String.h>
     2 #include <stdio.h>
     3 #include <malloc.h>
     4 
     5 
     6 #define Num 41
     7 #define killman 4
     8 
     9 void josephus_sort()
    10 {
    11     int man[Num]={0};
    12     int count=1;
    13     int i=0;
    14     int pos=-1;
    15     while(count<=Num)
    16     {
    17         do
    18         {
    19             pos=(pos+1)%Num;//环处理
    20             if (man[pos]==0)
    21             {
    22                 i++;
    23             }
    24             if (i==killman)
    25             {
    26                 i=0;
    27                 break;
    28             }   
    29         }while(1);
    30         man[pos]=count;
    31         printf("the %2d people die! the number of josephus is %2d
    ",pos+1,man[pos]);
    32 
    33         count++;
    34     }
    35 }
    36 
    37 
    38 
    39 int  main(void)
    40 {
    41 
    42     printf("the solve of josephus sort!
    ");
    43 
    44     josephus_sort();
    45     return 0;
    46 }
     
    3 现在接着上面的问题,升级一下:n个人坐成一个圈,现在每个人都拿一个随机写有数字的字条,游戏开始,任选一个数字m。从第一个人开始进行,按照编号重新开始报数,报道m的人出列,并且将其手中的数字作为新的出列数字。然后从下一个人开始重新从1开始报数,如此循环下去,问最后剩下来哪个人?
     1 /*
     2 由于在这里下一个决定出列的数字随机生成的,而且总的个数是可以自己定义的;
     3 在这里我们采用链表的方式来解答。
     4 */
     5 
     6 
     7 #include <string.h>
     8 #include <stdio.h>
     9 #include <malloc.h>
    10 #include <time.h>
    11 
    12 #define random_len 10
    13 
    14 typedef struct node 
    15 {
    16     int number;  //游戏者编号
    17     int psw;    //出列数字
    18     struct node *next;        //指针域,指向下一个节点
    19 }Lnode,*linklist; 
    20 
    21 
    22 
    23 void circleFun(linklist *list,int m)
    24 {
    25     linklist p,q;
    26     q=p=*list;
    27     while(q->next!=p)
    28     {
    29         q=q->next;
    30     }
    31     printf("the gamer out the list in this order!
    ");
    32     while(p->next!=p)
    33     {
    34         for (int i = 0; i < m-1; i++)
    35         {
    36             q=p;
    37             p=p->next;
    38         }
    39         q->next=p->next;
    40         printf("the %d people pop,the number in his hand is %d
    ",p->number,p->psw );
    41         m=p->psw;
    42         free(p);
    43         p=q->next;
    44     }
    45 
    46     printf("the last one is %d,the number in his hand is %d 
    ",p->number,p->psw );
    47 }
    48 
    49 void insertlist(linklist *list,linklist q,int number ,int psw)
    50 {
    51     linklist p;
    52     p=(linklist)malloc(sizeof(Lnode));
    53 
    54     p->number=number;
    55     p->psw=psw;
    56     if (!*list)
    57     {
    58         *list=p;
    59         p->next=NULL;
    60     }
    61     else
    62     {
    63         p->next=q->next;
    64         q->next=p;
    65     }
    66 }
    67 
    68 
    69 int  main()
    70 {
    71     linklist list1=NULL,q=NULL,list;
    72     int num,m_number; //m_number为第一个决定出列的数字;
    73     int e;
    74     printf("the solve of complex josephus problem
    ");
    75     printf("please input the number of people who join the game:");
    76     scanf("%d",&num);
    77     srand(time(NULL));
    78     for (int i = 0; i < num; i++)
    79     {
    80         e=rand()%10;
    81         printf("the number in %d people's hand %d 
    ",i+1,e);
    82         insertlist(&list1,q,i+1,e);
    83         if (i==0)
    84         {
    85             q=list1;
    86         }
    87         else
    88             q=q->next;
    89     }
    90     q->next=list1;
    91     list=list1;//循环链表
    92 
    93     printf("please input the number first input:
    ");
    94     scanf("%d",&m_number);
    95     circleFun(&list,m_number);
    96     printf("
    ");
    97     return 0;
    98 }
  • 相关阅读:
    golang的string是包使用
    OTHER状态的mongodb副本集成员转换为独立的新副本集primary
    linux命令行快捷键
    如何配置vcodes成最美观的样子,让你从此爱上代码
    记一次Lock wait timeout异常的排查过程
    mysql变更上线流程
    go build 使用
    Makefile文件
    解决 windows10系统和AOC显示器时不时地闪现黑屏问题
    feign调用添加header参数
  • 原文地址:https://www.cnblogs.com/tao-alex/p/5919092.html
Copyright © 2020-2023  润新知