蓝桥杯 - 猴子选大王 (约瑟夫问题)
标题:猴子选大王
一群猴子要选新猴王。新猴王的选择方法是:让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 }