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

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

输入格式:

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

输出格式:

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

输入样例:

11

输出样例:

7

code:(约瑟夫环问题)

方式一:

#include <stdio.h>
int main()
{
    int i, n, cnt1 = 0, cnt2 = 0;
    scanf("%d", &n);
    int a[n];
    for (i = 0; i < n; i++){
        a[i] = 0;
    }
    i = 0;
    while (1){
        
        if (a[i] != -1){
            cnt1++;
        }
        if (cnt1 == 3){
            a[i] = -1;
            cnt1 = 0;
            cnt2++;
        }
        if (cnt2 == n){
            printf("%d\n", i + 1);
            break;
        }
        i == n - 1 ? i = 0 : i++;
    }
    return 0;
}

设一个数组a[i],两个计数器cnt1,cnt2。a[i]从第一个数往后数,cnt1负责从1计到3,每数到3,将数组项记为“-1”,同时只有数组项不为“-1”时,cnt1才可加一。cnt2负责数有几个猴子退出(每当cnt1满3了加1)。当cnt2计到最后一个n时,看此时是第几个猴子(i+1)。

方式二:(递归算法)

#include<stdio.h>
int f(int);

int main(){
	int n;
    scanf("%d",&n);
	printf("%d\n",f(n)); 
	return 0;
}

int f(int n){
	int ret;
	if(n==1) ret=1;
	if(n==2) ret=2;
	if(n>=3){
		f(n-1)<=(n-3) ? (ret=(f(n-1)+3)): (ret=f(n-1)-(n-3));
	}
	return ret;
}

f(1)={1}=1

f(2)={1,2}=2

f(3)={1,2,3}  <第一次去掉3,变成>  {1,2}  <根据f(2)选第2个>  2

f(4)={1,2,3,4}  <去3,从4排序>  {4,1,2}  <第2个>  2

f(n)={1,2,3,……,n}  <去3,从4排序>  {4,5,6,……,n,1,2}  <选第f(n-1)个>  

注意(?:)语句,?比 = 的优先级高,所以?后的表达式要加括号,不然左值非变量,报错。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值