PTA 猴子选大王 (约瑟夫环问题)

Maha ·
更新时间:2024-09-20
· 967 次阅读

题目描述:

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

输入格式:

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

输出格式:

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

输入样例:

11

输出样例:

7

思路分析: 这是一道类约瑟夫环问题。可以把圈子大小创建为一个数组,并把每只猴子初始值赋值为1,当猴子报到3退出圈子时数值变为0。这个数值改变过程每执行一次,k加1,当k == N-1时,即出局人数k,剩余人数为1,游戏结束。 而约瑟夫环问题,可以简单化为数组重复从0到N-1的执行。在循环中添加判断条件,把数值为0的数组元素跳过。当遇到数值为1的元素,执行if的语句块,在语句块通过count计数,当count == 3,数值变为0,k++,count重新计数,变为0。 当数组下标移动到最大值时,数组重新循环,可以理解为数组头尾相接,即一个环,而count计数并不受影响,仍然可以想象为一个圈相接报数。 代码: #include int main() { int N, i, count = 0, k = 0, flag = 0; //count计数作为报数,是否为3的判断。k计算出局人数,当人数剩余1即可结束。flag标记最后一只数值为1的猴子。 scanf("%d", &N); int n[N]; //创建一个与猴子人数相同的数组,每个元素代表一只猴子。 for(i = 0; i < N; i++) n[i] = 1; //当猴子仍参与报数游戏时,数值为1,当猴子出局后,数值为0,以此判断该猴子是否参与报数游戏。 while(k != N-1) //当k == N-1,即剩余人数为1,该猴子为大王,游戏结束。 for(i = 0; i < N; i++) if(n[i] == 1) //n[i]等于0的猴子,则跳过,不参与报数。 { flag = i; count++; //每一只猴子报数,count加1。 if(count == 3) //当n[i]猴子报到count==3。 { n[i] = 0; //猴子出局。 k++; //出局人数加1。 count = 0; //count重新报数。 } } //可以简单理解循环条件只是判断游戏是否继续,循环过程是重复for循环执行,即数组下标重复移动,头尾相接。 printf("%d", flag+1); //因为数组从0开始。 return 0; }

解释的会比较详细,觉得好可以多多关注点赞


作者:詹汉杰



约瑟夫环问题 约瑟夫环

需要 登录 后方可回复, 如果你还没有账号请 注册新账号