7-28 猴子选大王 (20 分)

一群猴子要选新猴王。新猴王的选择方法是:让N只候选猴子围成一圈,从某位置起顺序编号为1~N号。从第1号开始报数,每轮从1报到3,凡报到3的猴子即退出圈子,接着又从紧邻的下一只猴子开始同样的报数。如此不断循环,最后剩下的一只猴子就选为猴王。请问是原来第几号猴子当选猴王?

输入格式:
输入在一行中给一个正整数N(≤1000)。

输出格式:
在一行中输出当选猴王的编号。

输入样例:
11
输出样例:
7

#include <stdio.h>

int main() {
	int n;
	scanf("%d", &n);
	if (n == 1) {
		printf("%d\n", n);
		return 0;
	}
	int arr[1000] = {0};          //定义数组,空间大小就给猴子最多的情况,1000,都赋初始值0
	for (int i = 1; i <= n; ++i) {    //根据输入的值,有多少只猴子,就把多少个元素改成1
		arr[i] = 1;
	}
	int a = 0;              //用于计数淘汰猴子的数量
	int b = 0;				//记录报数的次数,用于计算   b%3
	int j = 1;				//定义下标
	while (a<(n-1))      //这里因为要留一只猴子,所以淘汰猴子数得小于猴子总数减一
	{
		if (arr[j] == 0) {      //这里思路关键点,和下面的if 是思路关键点,如果此下标数组的值为0,则跳过
			j++;                    
			if (j == (n+1) ) {         //判断是不是最后一只猴子,如果本轮结束,继续从1开始报数
				j = 1;
			}
			continue;
		}
		b++;
		if (b%3 == 0) {         //如果报数的是3的倍数,则淘汰,改下标元素赋值为0
			arr[j] = 0;
			a++;                  //记录淘汰个数
		}
		j++;
		if (j == (n+1) ) {
			j = 1;
		}
	}
	for (int k = 1; k <= n; ++k) {
		if (arr[k] == 1) {
			printf("%d\n", k);           //得到仅剩的猴子
		}
	}
	return 0;
}

一开始想的用循环链表,但是发现循环链表也不怎么好实现。于是用数组实现。总体思路就是创个数组,每个元素代表一直猴子,给所有猴子一个黄牌(代码赋值为1),然后报数为3倍数的猴子,将黄牌换成红牌(重新赋值为0)但是不离场,继续报数,当第二轮报数时,如果遇到拿红牌的猴子(值为0的元素),则跳过。一直循环直到剩下一只猴子。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值