D a t e : 2022 − 10 − 01 \color{FF99FF}{Date:2022-10-01} Date:2022−10−01
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次,中间切一刀,会得到多少面条呢?
🍇思路🍇
思路:题目的关键在于“对折”。对折的基础是只有一根面条,与简单的多根面条堆叠在一起不一样,每一次对折时,弯曲部位都会形成一根新的面条,解题的关键就是找到这个规律。多列几组数据可以更方便的找到这个规律
对折次数 | 所得根数 |
---|---|
0 | 1 |
1 | 3 |
2 | 5 |
3 | 9 |
4 | 17 |
从上面四组数据可以找出下面的规律:
对折 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开始,初始面条数为2
总次数 = 2;
for (i = 1; i < 对折次数; i++)
{
总次数 += 2^(i - 1);
}
- 递归算法
相对于迭代,递归的方式有时候可能会比较绕,比较难理解,这里先说下怎么去更好的理解递归,要怎么使用递归
递归三部曲 - 确定递归函数的参数和返回值
- 确定终止条件
- 确定单层递归的逻辑
🍇代码🍇
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. 大衍数列🍎
🍆题目 🍆
大衍数列规律如下:
- 其奇数项的值是序号平方减一再除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呢?
🌺思路🌺
题目给出三个关键信息
- X生物每3分钟分裂一次
- Y生物每2分钟分裂一次
- 一个新生的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;
}