蓝桥杯 - 猴子选大王 (约瑟夫问题)

标题:猴子选大王

一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?

 

输入格式:

 

输入在一行中给一个正整数N(≤1000)。

 

输出格式:

 

在一行中输出当选猴王的编号。

 

输入样例:

11

 

输出样例:

7

思路一:用数组模拟一个环,存储第下标+1位猴子是否退出(因为下标从0开始),数组初始化为0,每次轮到数3的猴子就将他的下标置为-1,最后一个下标不为-1的猴子就是选中的王。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1000; //共有N个猴子
 5 
 6 int a[N];   //用数组和%操作模拟圈
 7 
 8 int index = 0;  //下标index
 9 int i = 1;  //用来对3计数
10 int counter;    //记录每次剩下的猴子个数
11 
12 int main()
13 {
14     int num;    //num是猴子的数量
15     cin >> num;
16     counter = num;
17 
18     while(counter > 1)
19     {
20         if(a[index] != -1)  //当下标为index的猴子还在圈内时
21         {
22             if(i == 3)
23             {
24                 a[index] = -1;  //将数到3的猴子退出圈子 ,将下标置为-1
25                 counter--;  //剩下的猴子总个数-1
26             }
27 
28             i++;
29 
30             if(i > 3)   //i=4时候,i要回到1
31             {
32                 i = i % 3;
33             }
34         }
35 
36         index++;
37 
38         if(index >= num)    //当下标达到了猴子总数时,要回到开头
39         {
40             index = index % num;
41         }
42 
43     }
44 
45     for(int i = 0; i < num; i++)
46     {
47         if(a[i] != -1)
48         {
49             cout << i + 1; //数组下标是从0开始的,要+1
50         }
51     }
52 
53     return 0;
54 }

 

思路2:使用递归思想

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 int fun(int n)
 5 {
 6     if(1 == n)
 7     {
 8         return 0;
 9     }
10 
11     return (fun(n - 1) + 3) % n;
12 }
13 
14 int main()
15 {
16     int n;
17     cin >> n;
18     cout << fun(n) + 1;
19     return 0;
20 }

 

posted @ 2019-03-19 17:24  WindSun  阅读(11290)  评论(1编辑  收藏  举报
博客已停更,文章已转移,点击访问