线性表应用:约瑟夫问题(猴子选大王)(循环链表,数组,递归)

  1 描述:一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。
  2 如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?
  3 //用循环链表
  4 #include<stdio.h>
  5 #include<stdlib.h>
  6 
  7 typedef struct node
  8 {
  9     int data;
 10     struct node *next;
 11 }node;
 12 
 13 node *create(int n)
 14 {
 15     node *head;
 16     node *p = NULL;
 17     head = (node *)malloc(sizeof(node));
 18     p = head;  //p为指向当前结点的指针 
 19     node *s;
 20     int i = 1;
 21     
 22     if(n != 0)
 23     {
 24         while(i <= n)
 25         {
 26             s = (node *)malloc(sizeof(node));   //临时的结点 
 27             s->data = i++;  //第一个结点的值为1 第二个结点的值为2 先给值i才++ 
 28             p->next = s;  //头结点的指针域指向第一个结点 
 29             p = s; //把第一个结点给当前结点  为了下一次p->next; 
 30         } 
 31         s->next = head->next; //s为插入的最后一个结点 让它指向头结点的下一个结点即第一个结点 
 32     }
 33     
 34     free(head);  //已经是一个环了 把头结点释放 
 35     
 36     return s->next; //s为最后一个结点它指向第一个结点 
 37     
 38 }
 39 
 40 int main(void)
 41 {
 42     int n;
 43     int m = 3;
 44     node *p;
 45     node *temp; //临时 
 46     scanf("%d",&n);
 47     p = create(n);
 48     m %= n; //m == 2 
 49     while(p != p->next)  //当自己指向自己时 就说明已经空了 
 50     {
 51         for(int i=1; i<m-1; i++)
 52         {
 53             p = p->next; //p原来指向第一个结点 p->next便是第二个结点 
 54         }
 55         
 56         //printf("%d->",p->next->data); //输入第三个结点  过程 
 57         
 58         temp = p->next;//开始删除结点 
 59         p->next = temp->next;
 60         free(temp);
 61         
 62         p = p->next;//从当前开始继续数 
 63     }
 64     
 65     printf("%d",p->data); //结果
 66     return 0;
 67 }
 68 
 69 
 70 //普通用数组
 71 #include<stdio.h>
 72 
 73 #define N 1000
 74 
 75 int main(void)
 76 {
 77     int monkey[N];
 78     int index = 0; //当下标 
 79     int i = 1;
 80     int counter; //记录猴子总数 
 81     
 82     int num;
 83     
 84     scanf("%d",&num); 
 85     counter = num; 
 86     
 87     while(counter > 1)
 88     {
 89         if(monkey[index] != -1)
 90         {
 91             if(i == 3)
 92             {
 93                 monkey[index] = -1;  //将数到3的猴子退出圈,并标志为-1
 94                 counter--; 
 95             }
 96             
 97             i++;
 98             
 99             if(i > 3) //如果i>3了 再回到1 
100             {
101                 i = 1;
102             }
103         }
104         
105         index++;   
106         if(index >= num)
107         {
108             index = 0;  //回到0 
109         }
110         
111     }
112     
113     for(int i = 0; i < num; i++)
114     {
115         if(monkey[i] != -1)
116         {
117             printf("%d",i+1);
118         }
119     }
120     
121     return 0;
122 }
123 
124 
125 
126 //用递归(强的一批)
127 #include<stdio.h>
128 
129 int fun(int n)
130 {
131     if(n == 1)
132     return 0;
133     
134     return (fun(n-1)+3)%n;
135 }
136 
137 int main(void)
138 {
139     int num;
140     scanf("%d",&num);
141     
142     printf("%d",fun(num)+1);
143     
144     return 0;
145 }
原文地址:https://www.cnblogs.com/ZhengLijie/p/12491229.html