一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?
输入格式:
输入在一行中给一个正整数N(≤1000)。输出格式:
在一行中输出当选猴王的编号。输入样例:
11
输出样例:
7
首先,分析题意,我们可以思考到以下几点:
1、利用数组给猴子编号,1号猴子储存在monkeys[0],代码如下:
for (int i=0;i<n;i++){
monkeys[i]=i+1;
}
2、选猴王时使用循环,只要猴子总数大于1,循环继续,且在判断后更新索引index。在循环中添加条件判断语句,如果猴子没有退出圈子,即monkeys[index]不等于0,开始轮流报数。继续判断,如果猴子报数报到3,退出猴王竞选,则把monkeys[index]中存储的数字改为0,将猴子总数记录进行减1,报的数据置0,后续循环报数时方便跳过。
while(sum>1){
if(monkeys[index]!=0){
step++;
if(step==3){
monkeys[index]=0;
step=0;
sum=sum-1;
}
}
index=(index+1)%n;
}
到这里,关键的代码都已经完成了,猴王也选出来了——循环过后monkeys[index]数组没有置0的猴子为猴王。
3、接下来,只需要利用循环找出monkeys[index]数组没有置0的猴子,输出其monkeys[index]数组值,即为猴王。
for(int i=0;i<n;i++){
if(monkeys[i]!=0){
printf("%d",monkeys[i]);
}
}
4、接下来将代码组合在一起,稍微修改,即可得到完整代码,其中,n为猴子总数,数组monkeys[]里面存储的是猴子的编号,sum是未退出猴王竞选的猴子总数,step是猴子报的数,逢3置0,index是猴子的循环索引。
代码如下:
#include <stdio.h>
int main(){
int n;
scanf("%d",&n);
int monkeys[n];
for (int i=0;i<n;i++){
monkeys[i]=i+1;
}
int step=0;
int sum=n;
int index=0;
while(sum>1){
if(monkeys[index]!=0){
step++;
if(step==3){
monkeys[index]=0;
step=0;
sum=sum-1;
}
}
index=(index+1)%n;
}
for(int i=0;i<n;i++){
if(monkeys[i]!=0){
printf("%d",monkeys[i]);
}
}
return 0;
}
答案正确!
总结:本题的难点在于找到猴王,这里巧妙地利用数组存储猴子编号,利用置0来表示猴子退出猴王竞选,用step记录循环报数,将猴子的编号逢3置0,用index不断地更新索引号码,不断地循环,直到最后,只留下一个没有被置0的数组(即sum=1),其中所保存的猴子编号也就是所选出的猴王了。