Description
一堆猴子都有编号,编号是1,2,3 …m ,这群猴子(m个)按照1–m的顺序围坐一圈,从第1开始数,每数到第n个(n<m),该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。 编程输出该猴子大王的编号。
Input
输入两个正整数 m,n(n<m)
Output
输出一个正整数,即猴子大王的编号
Sample Input
10 3 |
---|
Sample Output
4 |
---|
Source Code
#include<stdio.h>
int main()
{
int m,n,number,count=1; //number记猴子剩余个数,count记当前报数
int monkey[999];
int t; //t记数组下标
int i;
printf("请输入猴子个数 m 和报数 n :");
scanf("%d%d",&m,&n);
number = m;
for(i=0;i<m;i++)
monkey[i]=i+1;
t=0;
while(number>1)
{
if(monkey[t]>0)
{
if(count!=n)
{
count++;
t=(t+1)%m; //t=(t+1)%m实现数组下标加1
}
else
{
monkey[t]=0;
count=1;
number--;
t=(t+1)%m;
}
}
else
{
t=(t+1)%m;
}
}
for(i=0;i<m;i++)
{
if(monkey[i]>0)
printf("猴子大王:%d\n",monkey[i]);
}
return 0;
}
Computational Results
Analyze
这是一个经典的约瑟夫环问题,在这里我采用的是 数组标志位 法,
大致解题思路就是,定义一个猴子数组(足够大)赋值为1—m,当猴子数量number>1时开始报数,报数为n的猴子出圈 此时令该地址的数据为0,待到猴子数量number=1时结束循环即终止报数。最后循环找出哪个地址的数据>0,输出数据即可
注意!!!
上述代码中实现数组下标加1,为什么用 t = (t + 1)%m,而不用 t++ 呢?
假设有10只猴子,当数组下标为9时(t = 9),t++就会使 t = 10,而我们要让 t = 0,需要重新拐回去报数(只报数据大于0的猴子),所以用 t = (t + 1)%m。