题目:
解答:
这道题,就是典型的约瑟夫环问题,可以采用数学方法解决,当然也可以用数组或者循环链表模拟报数过程。
在这里,简单介绍以下数学思路。
假设有5个猴,那么第一轮报数为:1 2 3 1 2,我们可以简单的分析得到,我们每一轮只用关心3是谁,所以我们可以对每一轮的猴进行标号。
1——2——3——4——5 ------- 4=(1+3)%5 倒序第五轮
3——4——出局——1——2 ------- 1=(1+3)%3 倒序第四轮
出局——1——出局——2——3 ------- 2=(2+3)%3 倒序第三轮
出局——1/3——出局——2——出局 ------- 2=(1+3)%2+2 倒序第二轮
出局——出局——出局——1——出局 ------- 1=1%1 倒序第一轮
经过这样的几轮,就得到最初的四号猴子是首领。如果,我们再倒序观察四号猴子的每一轮编号,就会发现 上一轮的编号=(当前编号+3)%(上一轮的猴数),因为不会有0的存在,所以如果余数结果是0,则说明他是上一轮的最后一位,即上一轮的编号=上一轮的猴数。
分析就到这里了,代码实现还是很简单的。
#include <stdio.h>
//约瑟夫环,动态规划解决,从最终结果逆向推导
int main(){
int N;
//index是当前编号,i是猴数
int index=1;
int i;
scanf("%d",&N);
//循环可以直接从2只猴开始
for(i=2;i<=N;i++){
index=(index+3)%i;
//如果余数结果是0,则说明他是上一轮的最后一位,即上一轮的编号=上一轮的猴数
if(index==0){
index=i;
}
}
printf("%d",index);
return 0;
}