递归经典题:幸运人士(STL 双Vector使用)+让人绝望后的成功+一天一夜的冥思苦想+对于蓝桥杯大赛的想法+努力不一定成功,但每一次的成功都需要格外的努力!

题目描述

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

输入

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

输出

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

样例输入

1
2
3

样例输出

1
2
2

个人分析:
首先,不得不吐槽一下,这个题我可是想了一天一夜啊。
第一步,我起初的想法是按照题目意思遇到奇数就删除那个元素 这让我想到了Vector里面写好了
的erase()函数来删除 然后我发现了:首先,Vector默认开辟的数组下标都是从0开始的,然后我们每删除一个元素很有趣的是vector会自动往前补齐。起初我的思路就是分奇偶进行删除 比如第一次我们就把(i+1)对2取余(下标从0开始) 如果i+1为奇数的话 那么我们就删除当前这个元素 然后原本的下标为1移到下标为0的地方 这时候我们就消除偶数位的元素 后面思路就是(i+k)%2 k就是在每次删除之后++一次 起初k=1 不过这样还是wa了,很不甘心啊,然后吃饭的时候也想思路,晚上睡觉的时候也想思路,更有在操作系统,毛概课上还是在想思路,最后得到了我的最终想法!

最终想法:
我们还是进行消除,但这次我们采用的是双vector 这也是我在网上学习的时候发现vector是可以直接覆盖的 比如以下核心代码:

 		int len=v.size();
        vector<int> v2(len/2);
        for(int i=1,j=0;i<len;i+=2,++j)
        {
            v2[j]=v[i];
        }
        v=v2;
        df(v);

这里我们有2个vector 一个是起初的v和用来存储消除后数组 我的想法是既然每次要消除奇数位置的元素 那么我们v2就直接取v的偶数位的元素 然后将v2来覆盖v 当我们的v的大小不等于1的话,我们就一直递归 每次就取偶数位的元素 覆盖原本的数组 直到数组内只有一个元素的时候就直接输出那一个 因为就是我们最终所需要的!

然后,对于这里,有一点必须想清楚才行,不然会wa很多次或许也想不明白错在哪儿

   int len=v.size();
   vector<int> v2(len/2);

第一,我们先求出我们目标vector的大小 赋值给len 然后对于v2呢 我们是每次取偶数位的 比如1 2 3 4 5 那么取2 4 大小为2 刚好是len的一半 那么对于1 2 3 4 5 6 那么取2 4 6 大小为3 也刚好是len的一半
那么如果我们每次取奇数位的呢?情况就不一样了咯

   int len=v.size();
   vector<int> v2(len/2+1);

看到不同了吗?还是举例子吧:
比如1 2 3 4 5 我们取 1 2 3 此时等于len的一半还要加1哦

这里我就只说取偶数方面了,如果我们给的是len/2+1 那么会有一个位置的元素补0 因为vector默认的值就是0 你没赋值 那么就是0 这样我们就多了一个数了 对我们的结果就会有一定影响 后面我把这里改了后居然奇迹般的AC了,成功得之不容易啊~~

Ps:

下周周末就要进行蓝桥杯比赛了,也是我第一次参加大型程序设计大赛,为比赛也是准备了许久,从一开始连个C的简单题目都写不好,各种BUG到后来慢慢理解了代码结构后开始了自学C++之路 学习STL 这里我还是得提一提我的java老师说的话:努力不一定成功,但每一次的成功都需要格外的努力,还有我的高中数学老师:你只有不断努力,才会让人觉得毫不费力 总体来说,对于这次大型比赛还是有点担心的,编程题目其实与做数学题一样,都是需要积累的,我依旧觉得自己积累的很少,但是还是会坚持走下去,大二这最后一期,对于编程题目我只想多接触多接触,因为有些算法确实别人写的很棒,思路很清晰,对比起来,觉得自己水平还是不够,依旧得努力!

具体代码如下:
AC

#include<iostream>
#include<vector>
using namespace std;
vector<int> vec;


void df(vector<int> v)
{
    if(v.size()==1)
    {
        cout<<v[0]<<endl;
        v.clear();
    }
    else
    {
        int len=v.size();
        vector<int> v2(len/2);
        for(int i=1,j=0;i<len;i+=2,++j)
        {
            v2[j]=v[i];
        }
        v=v2;
        df(v);
    }

    /*for(int i=0;i<v.size();i++)
    {
        cout<<v[i]<<endl;
    }*/
    //return v[0];
}
int main()
{
    int n;
    while(cin>>n&&n)
    {
        vec.clear();
        for(int i=0;i<n;i++)
        {
            vec.push_back(i+1);
        }
        df(vec);
        vec.clear();
        /*for(int i=0;i<vec.size();i++)
        {
            cout<<vec[i]<<endl;
        }*/
    }

    return 0;
}
学如逆水行舟,不进则退

猜你喜欢

转载自blog.csdn.net/weixin_42429718/article/details/88587796