【Code Pratice】—— 切面条、大衍数列、门派制作、方阵转置、微生物繁殖

D a t e : 2022 − 10 − 01 \color{FF99FF}{Date:2022-10-01} Date20221001

G a f f e s \color{FF99FF}{Gaffes} Gaffes i s \color{FF99FF}{is} is a c c i d e n t a l l y \color{FF99FF}{accidentally} accidentally s a y \color{FF99FF}{say} say t h e \color{FF99FF}{the} the t r u t h ! \color{FF99FF}{truth!} truth!

🍓1. 切面条🍓

🍇题目🍇

一根高筋拉面,中间切一刀,可以得到2根面条。如果先对折1次,中间切一刀,可以得到3根面条。如果连续对折2次,中间切一刀,可以得到5根面条。 那么,连续对折10次,中间切一刀,会得到多少面条呢?

🍇思路🍇

思路:题目的关键在于“对折”。对折的基础是只有一根面条,与简单的多根面条堆叠在一起不一样,每一次对折时,弯曲部位都会形成一根新的面条,解题的关键就是找到这个规律。多列几组数据可以更方便的找到这个规律

对折次数所得根数
01
13
25
39
417

从上面四组数据可以找出下面的规律:
对折 0 次:2根 --> 2
对折 1 次:3根 --> 2 + 2 ^0
对折 2 次:5根 --> 2 + 2^0 + 2^1
对折 3 次:9根 --> 2 + 2^0 + 2^1 + 2^2
对折 4 次:17根 --> 2 + 2^0 + 2^1 + 2^2 + 2^3
也就是说每多对折 N 次,那么就能多得到 2^(N - 1) 根面条,找到这个规律,题目就很好解了。

按照上面的规律,将对折0次到对折N次得到的面条数相加就是题目要求所得,而规律性的暴力题解,可以直接联想到 [迭代] 和 [递归] 两种方式

  1. 迭代算法
    因为从对折1次时才实际增加面条数,所以遍历次数从1开始,初始面条数为2
总次数 = 2;
for (i = 1; i < 对折次数; i++)
{
    总次数 += 2^(i - 1);
}
  1. 递归算法
    相对于迭代,递归的方式有时候可能会比较绕,比较难理解,这里先说下怎么去更好的理解递归,要怎么使用递归
    递归三部曲
  2. 确定递归函数的参数和返回值
  3. 确定终止条件
  4. 确定单层递归的逻辑

🍇代码🍇

int CutNoodles(int i_Foldnum)
{
    if (0 > i_Foldnum)
    {
        return -1;
    }

    int o_Noodlenums = 2;
    #if 0
    /* 迭代 */
    for (int i = 1; i <= i_Foldnum; i++)
    {
        int Singlenums = 1;
        /* 对折 N 次,增加 2^(N - 1) 根 */
        int j = i - 1;
        while (j--)
        {
            Singlenums *= 2;
        }
        o_Noodlenums += Singlenums;
    }
    return o_Noodlenums;
    #else
    /* 递归 */
    if (0 == i_Foldnum)
    {
        return o_Noodlenums;
    }
    else
    {
        return o_Noodlenums * CutNoodles(i_Foldnum - 1) - 1;
    }
    #endif
}

🍎2. 大衍数列🍎

🍆题目 🍆

大衍数列规律如下:

  1. 其奇数项的值是序号平方减一再除2
  2. 其偶数项的值是序号平方再除2
    例子:
    0 2 4 8 12 18 24 32 40 50

🍆思路🍆

按照题目所给规律直接写逻辑就好了

🍆代码 🍆

int DYSequence(vector<int>& i_Array, int i_Length)
{
    if (0 > i_Length)
    {
        return -1;
    }

    for (int i = 1; i <= i_Length; i++)
    {
        if (0 == (i % 2))
        {
            i_Array[i - 1] = (i * i) / 2; 
        }
        else
        {
            i_Array[i - 1] = ((i * i) - 1) / 2;
        }
    }

    return 0;
}

🍅3. 门牌制作🍅

🌸题目🌸

小蓝要为街道的住户制作门牌号,制作的方法为每个门的制作都会先将对应的0~9这10个数字制作出来,然后再贴到门牌上
如果要为N位住户制作门牌号,共需要制作多少个字符2

🌸思路🌸

这实际上是一个求数值每一位上的数字问题,只需要从第一位住户开始,统计对应门牌号上数字2的位数的总和即可

🌸代码🌸

int HouseNumPro(int i_HouseNum)
{
    if (0 >= i_HouseNum)
    {
        return -1;
    }

    int o_CharNum = 0;
    for (int i = 1; i <= i_HouseNum; i++)
    {
        int j = i;
        while (j)
        {
            if (2 == (j % 10))
            {
                o_CharNum++;
            }
            j /= 10;
        }
    }
    return o_CharNum;
}

🥭4. 方阵转置🥭

🌷题目🌷

给定一个NxM的矩阵,求它的转置。

🌷思路🌷

转置的思路很简单,就是长变宽,宽变长
将原矩阵的N当作转置后的M,原矩阵的M当作转置后的N即可

🌷代码🌷

int SquareMatrixTranspose(vector<vector<int> > i_SquMX, int i_Length, int i_Width)
{
    if (0 > i_Length || (0 > i_Width))
    {
        return -1;
    }
    for (int i = 0; i < i_Width; i++)
    {
        for (int j = 0; j < i_Length; j++)
        {
            cout << i_SquMX[j][i] << "\t";
        }
        cout << endl;
    }
    cout << endl;
    return 0;
}

🍊5. 微生物增殖🍊

🌺题目🌺

假设有两种微生物 X 和 Y
X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍)。
一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y。
现在已知有新出生的 X=10, Y=89,求60分钟后Y的数目。
如果X=10,Y=90呢?

🌺思路🌺

题目给出三个关键信息

  1. X生物每3分钟分裂一次
  2. Y生物每2分钟分裂一次
  3. 一个新生的X,半分钟后吃掉一个Y

只要按照上面三个关键点进行X和Y的数量计算即可,为了方便计算,关键信息[0.5 2 3]都扩大两倍为整型[1 4 6]

🌺代码🌺

int MicrobialReproducte(int i_Xnum, int i_Ynum, int i_Minute)
{
    int XSum = i_Xnum;
    int YSum = i_Ynum;
    for (int i = 1; i <= i_Minute * 2; i++)
    {
        if (i % 2 == 1)
        {
            YSum -= XSum;
        }
        if (i % 6 == 0)
        {
            XSum = XSum * 2;
        }
        if (i % 4 == 0)
        {
            YSum = YSum * 2;
        }
    }
    return YSum;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ltd Pikashu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值