[练习]幸运人士

幸运人士

时间限制 : 1.000 sec 内存限制 : 128 MB

题目描述

一次大型派对的最后节目是选出一位幸运人士,该人士将获得派对组织者准备的一个钻石戒指。
而选择幸运人士的办法是让所有人员一字排列,然后从左至右点数,凡是奇数号的全部剔除。
对于剩下的人员,又从左至右点数,逢奇数号就剔除。
如此不断递归下去,直到只剩下一个人为止,此人即为幸运之人。
请设计一个递归算法计算幸运之人所在的位置。

输入

多组数据,每组输入一个正整数n。

输出

输出最后剩下的那个人的位置。

样例输入

1
2
3

样例输出

1
2
2

解题思路

看到题目其实第一反应是用vector开动态数组,但是要用递归的话就有些懵,不知道从何下手,想去找博客看看有没有思路解析,但是自己看不明白。。。所以就把链接放在这里,想看的自己直接看:(我们学校超级厉害的学长写的)
链接: 幸运人士(STL双vector使用).

我要讲的,是另外一种超级简单的解法,虽然也有博主直接放出来代码,但是没有详细介绍。。。所以我看到代码的时候真的一脸懵。。。没想到自己能找到规律写出来,就来讲一讲:

根据题目,我们可以作出下图:
在这里插入图片描述

我们仔细观察 n 和 m 的关系,可以尝试推出规律:

n 和 m 可以按照 每 2t(t=0;t++)个为一组 来分组,每一组的m都是上一组m的二倍,n的个数也是上一组的二倍;
所以我们的递归就可以反过来,令f(n)=m,
n的值是二倍二倍增长的,故前一次递归是f(n/2),m增长一倍,故m=f(n/2)*2。
递归的结束条件即,当n=1时,m=1。

在这里插入图片描述

关键公式就出来啦,现在再看代码应该就会很明白了:

#include <bits/stdc++.h>
using namespace std;

int f(int n){
    if(n==1) return 1;//递归结束条件
    else{
        return f(n/2)*2;
    }
}

int main(){
    int n;
    while(cin>>n){
        cout<<f(n)<<endl;
    }
    return 0;
}

希望能对大家有帮助!!

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值