💀来了奥💀
🤣又来看图来了🤣
问题描述:有n只猴子,按顺时针方向围成一圈选大王(编号为1~n),从第1号开始
圾数,一直数到m,报到m的猴子出圈,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下- 只候子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号,
输入:两个整数,第一个是n,第二个是m(0<m.n300)
输出:按出圈顺序输出猴子的编号及最后猴王的编号。
问题分析:借助数组实现,后续会使用链表给出另外一种解决方法。
(1)由于每个猴子只能是在圈内和在圈外两种状态之一,用非0表示在圈内,用0表示在圈外。使 日数组存储每个猴子的编号(假设数组名为a),初始时a[0]存放第1个猴子的编号1,则li-1]的值为第 ;个猴子的编号i,如果编号为a[i]的猴子出圈,则将其编号a[j]置成0;
(2)开始时,数组元素的值为猴子编号(1~n),n个猴子都在圈内;
(3)模拟猴子报数、出圈、选大王过程,直到圈内只剩下一个猴子为止。
算法实现:
(1)准备工作。定义大小为n的int数组a,使用循环数组模拟n个猴子围成一圈。n个猴子,下标 范围是0~n-1,a[i]存放猴子的编号计1,编号为非0表示猴子在圈内。
(2)报数过程。j为猴子的下标,j的初值应该为第1个报数猴子的前一位下标(如果从编号为1 的猴子开始报数,则j=n-1),开始报数时,计算报数猴子的下标,为了表示0下标是n-1下标的下一 个,报数时使用求余技术计算下标,即j=(j+1)%n,每次报数只数圈内的猴子,即fi[ij)kt+;(k 为计数器)。
(3)出圈。报数为m的猴子出圈,则a[j]=0;
(4)循环(2),(3),直到圈内只有一个猴子,也就是要有n-1个猴子出圈。
程序的参考代码如下:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n,m; //表示n个猴子,报数m
printf("请输入猴子个数和报的数");
scanf("%d%d",&n,&m);
int* a=(int *)malloc(sizeof(int)*n);//动态申请储存空间
for(int i=0; i<n; i++)
a[i]=i+1;
printf("出圈顺序:");
int j=n-1;
for(int i=1; i<n; i++)
{//n-1个猴子出圈
int k=0;//报数器
do
{
j=(j+1)%n;//报数猴子下标
if(a[j])
k++;//猴子报数
}while(k<m);
printf("%d ",a[j]);
a[j]=0;
}
printf("\n后出圈的猴子编号:");
for(int i=0; i<n; i++)
{
if(a[i]!=0)
printf("%d",a[i]); //释放空间
}
free(a);
return 0;
}
例:
小伙伴自己也运行一下
下期见