一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?
输入格式:
输入在一行中给一个正整数N(≤1000)。
输出格式:
在一行中输出当选猴王的编号。
输入样例:
11
输出样例:
7
#include <stdio.h>
int main()
{
int N;
scanf("%d", &N);
int monkeys[1000]; //准备报数的猴子(编号)
int king[1000] = { 0 }; //报完数留下的猴子(编号)
int baoshu[1000]; //猴子报的数
int i;
for (i = 0; i < N; i++)
{
monkeys[i] = i + 1;
} //初始化,按顺序记录猴子编号
int num_last = N; //初始化,上次报数留下的猴子(数目)
int monkeys_yushu = N % 3; //初始化,一开始的猴子数目除以3的余数
int baoshu_start = 1; //初始化,本次报数的起始数字
int j, k;
int round; //确定每次报数的回合数,报1-3为一回合,未报满计一回合,如3、1、2、3、1计三回合
int num_over;
if (monkeys_yushu == 0)
{
round = N / 3;
}
else {
round = N / 3 + 1;
}
if (num_last == 1)
{
king[0] = 1;
}
else {
while (num_last != 1)
{
int num_this = 0, times = 0;
for (i = 1; i <= round; i++)
{
j = baoshu_start;
baoshu_start = 1;
for (; j <= 3; j++)
{
times++;
if (times < num_last)
{
baoshu[times - 1] = j;
}
else if (times == num_last)
{
baoshu[times - 1] = j;
num_over = j; //记录本次报数的最后一个数字
break;
}
}
} //本次报数结束
for (i = 0; i < num_last; i++)
{
if (baoshu[i] != 3)
{
king[num_this] = monkeys[i];
num_this++;
}
} //找出本次报数留下的猴子(编号)
for (i = 0; i < num_this; i++)
{
monkeys[i] = king[i];
} //将本次报完数留下的猴子(编号)赋给准备下一次报数的猴子(编号)数组
baoshu_start = num_over + 1;
if (baoshu_start == 4)
{
baoshu_start = 1;
} //确保每次报数的起始数字不超过3
switch (baoshu_start)
{
case 1:
monkeys_yushu = num_this % 3;
if (monkeys_yushu == 0)
{
round = num_this / 3;
}
else {
round = num_this / 3 + 1;
}
break;
case 2:
monkeys_yushu = (num_this - 2) % 3;
if (monkeys_yushu == 0)
{
round = num_this / 3 + 1;
}
else {
round = num_this / 3 + 2;
}
break;
case 3:
monkeys_yushu = (num_this - 1) % 3;
if (monkeys_yushu == 0)
{
round = num_this / 3 + 1;
}
else {
round = num_this / 3 + 2;
}
break;
default:;
}
num_last = num_this;
}
}
printf("%d", king[0]);
return 0;
}
注意事项:
如有问题,欢迎提出。