7-9 乘法口诀数列

本题要求你从任意给定的两个 1 位数字 a1​ 和 a2​ 开始,用乘法口诀生成一个数列 {an​},规则为从 a1​ 开始顺次进行,每次将当前数字与后面一个数字相乘,将结果贴在数列末尾。如果结果不是 1 位数,则其每一位都应成为数列的一项。

输入格式:

输入在一行中给出 3 个整数,依次为 a1​、a2​ 和 n,满足 0≤a1​,a2​≤9,0<n≤103。

输出格式:

在一行中输出数列的前 n 项。数字间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

2 3 10

输出样例:

2 3 6 1 8 6 8 4 8 4

样例解释:

数列前 2 项为 2 和 3。从 2 开始,因为 2×3=6,所以第 3 项是 6。因为 3×6=18,所以第 4、5 项分别是 1、8。依次类推…… 最后因为第 6 项有 6×8=48,对应第 10、11 项应该是 4、8。而因为只要求输出前 10 项,所以在输出 4 后结束。

# 读取输入的 a1, a2 和 n
a1, a2, n = map(int, input().split())

# 特殊情况处理:如果 n 为 1,直接输出 a1
if n == 1:
    print(a1)
# 如果 n 为 2,直接输出 a1 和 a2
elif n == 2:
    print(f"{a1} {a2}")
else:
    # 初始化数列,包含前两项
    sequence = [a1, a2]
    # 用于记录当前参与乘法运算的索引
    index = 0

    # 当数列长度小于 n 时,继续生成新的项
    while len(sequence) < n:
        # 计算当前两项的乘积
        product = sequence[index] * sequence[index + 1]
        # 将乘积转换为字符串,方便按位处理
        product_str = str(product)
        # 遍历乘积的每一位
        for digit in product_str:
            # 将每一位数字添加到数列中
            sequence.append(int(digit))
            # 如果数列长度达到 n,停止添加
            if len(sequence) == n:
                break
        # 移动到下一组参与乘法运算的项
        index += 1

    # 输出数列的前 n 项,用空格分隔
    print(" ".join(map(str, sequence)))

综上所述,这段代码通过对 n 的不同情况进行处理,实现了根据给定的前两项 a1 和 a2 生成乘法口诀数列并输出前 n 项的功能。

temp[++temp_len] = 0;前置自增运算符 ++ 会先将 temp_len 的值加 1,然后返回加 1 后的值。将数字 0 赋值给 temp[1],即 temp[1] = 0;

temp[temp_len++] = 0;由于后置自增操作符 ++ 的特性,它会先返回 temp_len 的当前值,然后再将 temp_len 的值加 1。将数字 0 赋值给 temp[0],即 temp[0] = 0;

  • input():这是 Python 的内置函数,用于从标准输入(通常是键盘)读取用户输入的一行内容,返回的是一个字符串。
  • split():字符串对象的方法,用于将字符串按空格分割成多个子字符串,并返回一个包含这些子字符串的列表。例如,若用户输入 2 3 10input().split() 会得到 ['2', '3', '10']
  • map(int, ...)map 函数会将 int 这个函数应用到传入的可迭代对象(这里是 input().split() 返回的列表)的每个元素上,将列表中的每个字符串元素转换为整数。所以 map(int, input().split()) 会把 ['2', '3', '10'] 转换为包含整数 23 和 10 的一个可迭代对象。
  • a1, a2, n = ...:使用解包赋值,将可迭代对象中的三个整数分别赋值给变量 a1a2 和 n。其中 a1 和 a2 是数列的前两项,n 是需要输出的数列项数。
  • if n == 1::判断 n 是否等于 1,如果是,则直接使用 print 函数输出 a1,因为此时只需要输出数列的第一项。
  • elif n == 2::如果 n 不等于 1,继续判断 n 是否等于 2。如果是,则使用 f-string 格式化字符串,将 a1 和 a2 用空格连接起来并输出,这是因为此时需要输出数列的前两项。
  • else::如果 n 既不等于 1 也不等于 2,说明需要按照常规逻辑生成数列。
  • sequence = [a1, a2]:初始化一个列表 sequence,并将 a1 和 a2 作为列表的前两个元素,这个列表用于存储生成的数列。
  • index = 0:初始化一个变量 index 为 0,用于记录当前参与乘法运算的元素在 sequence 列表中的索引。
  • while len(sequence) < n::使用 while 循环,只要 sequence 列表的长度小于 n,就继续循环,以不断生成新的数列项。
  • product = sequence[index] * sequence[index + 1]:计算 sequence 列表中当前索引 index 对应的元素和下一个元素的乘积,将结果存储在 product 变量中。
  • product_str = str(product):将乘积 product 转换为字符串类型,这样可以方便地按位处理。
  • for digit in product_str::遍历乘积字符串 product_str 中的每一个字符。
  • sequence.append(int(digit)):将遍历到的字符转换为整数,并添加到 sequence 列表的末尾。
  • if len(sequence) == n::判断 sequence 列表的长度是否达到了 n,如果达到了,则使用 break 语句跳出内层的 for 循环,停止添加新元素。
  • index += 1:将 index 加 1,以便在下一次循环中计算下一组相邻元素的乘积。
  • print(" ".join(map(str, sequence))):使用 map(str, sequence) 将 sequence 列表中的每个整数元素转换为字符串,然后使用 " ".join(...) 方法将这些字符串用空格连接起来,最后使用 print 函数输出连接后的字符串。
可以将 `int temp[4];` 改为 `int temp[3];`。下面来详细分析原因:

### 数组用途分析
在代码里,`temp` 数组的作用是临时存储两个一位数相乘结果的每一位数字。由于输入的 `a1` 和 `a2` 满足 `0 ≤ a1, a2 ≤ 9`,那么它们相乘的结果范围是 `0` 到 `81`(`9 * 9 = 81`)。

### 结果位数分析
- 当乘积为 `0` 时,结果是一位数。
- 当乘积在 `1` 到 `9` 之间时,结果同样是一位数。
- 当乘积在 `10` 到 `81` 之间时,结果是两位数。

所以,两个一位数相乘的结果最多是两位数,再考虑到可能为 `0` 这种特殊情况,存储乘积每一位数字最多需要 `3` 个元素的数组就足够了,即 `int temp[3];` 是可行的。

### 代码修改示例
以下是将 `int temp[4];` 改为 `int temp[3];` 后的完整代码:
```c
#include <stdio.h>

#define MAX_N 1000

int main() {
    int a1, a2, n;
    // 读取输入的 a1, a2 和 n
    scanf("%d %d %d", &a1, &a2, &n);

    int sequence[MAX_N];
    // 初始化数列的前两项
    sequence[0] = a1;
    sequence[1] = a2;

    int len = 2;  // 当前数列的长度
    int index = 0;  // 用于记录当前参与乘法运算的索引

    // 当数列长度小于 n 时,继续生成新的项
    while (len < n) {
        int product = sequence[index] * sequence[index + 1];
        int temp[3];  // 临时存储乘积的每一位数字,因为最大 9*9 = 81,最多两位
        int temp_len = 0;

        // 处理乘积的每一位
        if (product == 0) {
            temp[temp_len++] = 0;
        } else {
            while (product > 0) {
                temp[temp_len++] = product % 10;
                product /= 10;
            }
        }

        // 反转存储的数字,使其顺序正确
        for (int i = temp_len - 1; i >= 0; i--) {
            sequence[len++] = temp[i];
            if (len == n) {
                break;
            }
        }

        index++;
    }

    // 输出数列的前 n 项,用空格分隔
    for (int i = 0; i < n; i++) {
        if (i > 0) {
            printf(" ");
        }
        printf("%d", sequence[i]);
    }
    printf("\n");

    return 0;
}
```
这样修改之后,代码的功能不会受到影响,同时还能减少不必要的内存开销。 

vector 是 C++ 标准模板库(STL)中的一个容器类,它表示一个动态数组。与传统的 C 数组相比,vector 具有以下优点:

  • 动态大小vector 可以在运行时动态地改变其大小,你可以根据需要添加或删除元素,而不需要在创建时指定固定的大小。
  • 自动内存管理vector 会自动管理其内部的内存,当元素数量增加时,它会自动分配更多的内存;当元素数量减少时,它会自动释放不再使用的内存,避免了手动管理内存带来的复杂性和潜在的内存泄漏问题。
  • 丰富的操作方法vector 提供了一系列方便的成员函数,如 push_back() 用于在末尾添加元素、pop_back() 用于删除末尾元素、size() 用于获取元素数量等,使对数组的操作更加方便和高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值