题目
一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?
输入格式:
输入在一行中给一个正整数N(≤1000)。
输出格式:
在一行中输出当选猴王的编号。
输入样例:
11
输出样例:
7
代码长度限制16 KB
时间限制400 ms
内存限制64 MB
思路
用数组的下标表示猴子的编号,数组的元素表示猴子报数的次序(eg:第N次报数元素值为N);
退出的猴子对应的元素值改为0;
剩一只猴子时停止报数;
遍历数组输出唯一不为零元素对应的下标。
代码
#include<stdio.h>
#define M 3 //报到M的猴子退出圈子
int main()
{
int N, i, k, count, index;
scanf("%d",&N); //总人数N
int a[N+1];
count = N; //剩余的人数
k = 0; //在N之后接着数
a[0] = 0;
for(i = 1; i<N+1; i++)a[i] = i; //从1开始用数组下标与标号一一对应
i = 1;
do{
for(i = 1; i<N+1; i++){
if(a[i] != 0 && a[i]%M==0){
a[i] = 0; //是3的倍数的变成零,相当于删除了
count--; //剩余个数减一
}else if(a[i] != 0 && a[i]%M!=0){
k++;
a[i] =N + k; //在N之后接着数
}
}
}while(count >1); //只剩一个数时循环结束
for(i = 1; i<N+1; i++){
if(a[i] != 0){
index = i; //最后一个非零数的下标
printf("%d",index);
}
}
return 0;
}
总结
这属于约瑟夫环问题。
使用数组,链表,递归皆可完成。