阶段小测

2023/12/15

此小测全部习题不得使用数组以及函数解答

# 1. 给定一个整数,请将该数各个位上的数字反转得到一个新数。新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零。编写程序,输入一个整数,输出反转后的新数。

// 输入输出示例:
// 为详细展示示例,所有的输入都添加了换行,实际编写输入打印可以不换行

// 示例 1:
// 输出
请输入:
// 输入
380
// 输出
新数为:83

// 示例 2:
// 输出
请输入:
// 输入
120
// 输出
新数为:21

# 解析

你已经在循环中处理了末尾为零的情况,但是有一点可以改进。可以在计算新数时,直接在结果之前乘以 10,并加上当前数字。这样在处理末尾零的情况时就不需要额外的条件判断了。

```cpp
while (n >= 1)
{
    b = n % 10;
    sum = sum * 10 + b;
    n /= 10;
}
```

# 参考答案

#include <iostream>
using namespace std;

int main() {
    int num;
    cout << "请输入一个整数:";
    cin >> num;

    if (num == 0) {
        cout << "新数为:0" << endl;
        return;
    }

    int reversed_num = 0;

    while (num != 0) {
        int digit = num % 10;
        reversed_num = reversed_num * 10 + digit;
        num = num / 10;
    }

    cout << "新数为:" << reversed_num << endl;
    return 0;
}

# 2. 角谷猜想是一种数学猜想,对于任意正整数,如果是奇数,则乘 31;如果是偶数,则除以 2。重复这个过程,最终总能够得到 1。编写程序,输入一个正整数,输出经过处理得到 1 的过程。

// 输入输出示例:
// 为详细展示示例,所有的输入都添加了换行,实际编写输入打印可以不换行

// 示例 1:
// 输出
请输入:
// 输入
5
// 输出
输出:16 8 4 2 1 End

// 示例 2:
// 输出
请输入:
// 输入
1
// 输出
输出:End

# 解析

变量 `b` 被声明但未被使用,可以去掉。
在奇数的情况下,将 `b` 设置为 `a` 并执行 `a*=3;` 操作,然后再执行 `a+=1;`,这两步可以合并成一步 `a = 3 * a + 1`。
#include <iostream>
using namespace std;

int main() {
    int num;
    cout << "请输入一个正整数:";
    cin >> num;
    while (num != 1) {
        cout << num << ' ';
        if (num % 2 == 0) {
            num = num / 2;
        } else {
            num = 3 * num + 1;
        }
    }
    cout << "End" << endl;

    return 0;
}

# 3. 给定一个正整数num,编写一个程序来判断它是否为完全数。完全数是指一个正整数等于除了它自身之外的所有正因子之和。例如,28是一个完全数,因为28的所有正因子(除了28本身)是1, 2, 4, 7, 14,它们的和为28。请设计一个程序,判断输入的整数是否为完全数,如果是,输出True,否则输出False

// 输入输出示例:
// 为详细展示示例,所有的输入都添加了换行,实际编写输入打印可以不换行

// 示例 1:
// 输出
请输入一个正整数:
// 输入
6
// 输出
True

// 示例 2:
// 输出
请输入一个正整数:
// 输入
26
// 输出
False

# 解析

循环条件中使用 i<n 可以确保遍历所有的因子,但可以进一步优化为 i <= n/2,因为大于 n/2 的数不可能是 n 的因子。
你还可以进一步优化循环条件,将其改为 i <= n/2,这样可以减少循环次数,提高效率。因为大于 n/2 的因子不可能存在。
#include <iostream>
using namespace std;

int main() {
    int num;
    cout << "请输入一个正整数:";
    cin >> num;

    // 负数和零不是完全数
    if (num <= 0) {
        cout << "False" << endl;
        return;
    }

    int sum = 0;
    for (int i = 1; i <= num / 2; ++i) {
        if (num % i == 0) {
            sum += i;
        }
    }

    if (sum == num) {
        cout << "True" << endl;
    } else {
        cout << "False" << endl;
    }

    return 0;
}

# 4. 有一天,一个农夫带着 100 个铜板去市场买鸡。他知道公鸡每只值 5 个铜板,母鸡每只值 3 个铜板,而小鸡三只值 1 个铜板。农夫总共买了 100 只鸡,问公鸡、母鸡、小鸡各买了多少?

// 输入输出示例:
// 为详细展示示例,所有的输入都添加了换行,实际编写输入打印可以不换行

// 输出
公鸡数量:0,母鸡数量:25,小鸡数量:75
公鸡数量:4,母鸡数量:18,小鸡数量:78
公鸡数量:8,母鸡数量:11,小鸡数量:81
公鸡数量:12,母鸡数量:4,小鸡数量:84
#include <iostream>
using namespace std;

int main() {
    for (int cocks = 0; cocks <= 20; ++cocks) {
        for (int hens = 0; hens <= 33; ++hens) {
            int chicks = 100 - cocks - hens;
            if (5 * cocks + 3 * hens + chicks / 3 == 100 && chicks % 3 == 0) {
                cout << "公鸡数量:" << cocks << ",母鸡数量:" << hens << ",小鸡数量:" << chicks << endl;
            }
        }
    }

    return 0;
}

# 5. 求 100999 之间的水仙花数。如果一个三位数 ABC,满足 ABC = A3 + B3 + C3,那么称 ABC 为水仙花数。例如,153 满足条件,因为 13 + 53 + 33 = 1 + 125 + 27 = 153。请找出所有满足条件的水仙花数。

// 输入输出示例:
// 为详细展示示例,所有的输入都添加了换行,实际编写输入打印可以不换行

// 输出
153 是水仙花数
370 是水仙花数
371 是水仙花数
407 是水仙花数

# 解析

这两种方法都是为了获取一个三位数中的十位数字。两者的差异在于取模运算的位置不同,但实际上这并不影响结果。关键是两者都正确地提取了十位数字。

具体来说,(num % 100) / 10 和 (num / 10) % 10 都是为了获得十位数字。(num % 100) 可以得到一个两位数,然后除以 10 就得到了十位数字。而 (num / 10) 得到的是一个去掉个位数字的两位数,然后取模 10 就得到了十位数字。

#include <iostream>
using namespace std;
int main() {
    for (int num = 100; num <= 999; ++num) {
        int digit1 = num / 100;
        int digit2 = (num / 10) % 10;
        int digit3 = num % 10;

        if (num == digit1 * digit1 * digit1 + digit2 * digit2 * digit2 + digit3 * digit3 * digit3) {
            cout << num << " 是水仙花数" << endl;
        }
    }

    return 0;
}

# 6. 一只青蛙从地面开始起跳,它一次可以跳1级台阶,也可以一次跳2级台阶,但是出于体力因素不允许连着两次跳2级台阶。求这只青蛙跳上一个n级台阶总共有多少办法?

不允许连着两次跳 2 级台阶,规定了在任意连续两步中,至少有一步是跳 1 级台阶。

// 输入输出示例:
// 为详细展示示例,所有的输入都添加了换行,实际编写输入打印可以不换行

// 示例 1:
// 输出
请输入台阶的级数 n:
// 输入
3
// 输出
青蛙跳上 3 级台阶的方法总数为: 3

// 示例 2:
// 输出
请输入台阶的级数 n:
// 输入
6
// 输出
青蛙跳上 6 级台阶的方法总数为: 9

# 思路

  • 令 f[n] 为跳 n 级台阶的方法数。
  • 用 g[n] 表示最后一步不是跳 2 级的走法数目,h[n] 表示最后一步跳 2 级的走法数目。
  • 显然有:f[n] = g[n] + h[n]
  • h[n] = g[n-2],因为在不能连着两次跳 2 级的情况下,倒数第二步不是跳 2 级,最后一步跳 2 级。
  • g[n] = g[n-1] + h[n-1],即倒数第二步的走法加上最后 1 级台阶的走法减去先 g[n-1] 再 1 级和先 h[n-1] 再 1 级。
  • f[n] = g[n] + h[n] = g[n-1] + g[n-3] + g[n-2]
  • f[n-1] = g[n-1] + h[n-1] = g[n-1] + g[n-3]
  • f[n] = f[n-1] + g[n-2]
  • g[n-2] = g[n-3] + h[n-3] = f[n-3]
  • 因此,有 f[n] = f[n-1] + f[n-3]

# 已知条件

  • f[0] = 1
  • f[1] = 1
  • f[2] = 2
  • f[3] = 3

# 负数的定义:

  1. 整数的拓展: 负数的引入是为了扩展整数的概念。在自然数和整数的基础上,引入了负数,使得数学体系更加完备。

  2. 小于零的实数: 从数轴的角度来看,负数位于零的左侧。对于实数集合,负数是小于零的实数。

  3. 符号表示: 负数通常用负号(-)表示,紧接在一个数值之前,例如-3,-5,-10 等。这个负号表示这个数在数轴上的位置相对于零是在左侧。

  4. 相反数: 一个数的相反数是与它在数轴上对称的数。例如,对于任何实数 x,其相反数是-x,而-x 的相反数是 x。相反数的引入使得负数在运算中更加灵活,同时满足加法的封闭性。

# 负数的运算规则:

  1. 加法: 负数与负数相加,结果为负数;正数与负数相加,结果可能为正数、负数或零,取决于它们的相对大小。

  2. 减法: 减去一个负数相当于加上它的相反数;负数减去正数,结果为负数。

  3. 乘法: 两个负数相乘,结果为正数;正数与负数相乘,结果为负数。

  4. 除法: 负数除以正数,结果为负数。

# 负数和正数关系

# 1. 定义

  • 正数(Positive Numbers): 正数是大于零的实数。在数轴上,它们位于零的右侧。正数用正号表示,例如 3,5,100 等。

  • 负数(Negative Numbers): 负数是小于零的实数。在数轴上,它们位于零的左侧。负数用负号表示,例如-2,-7,-50 等。

# 2. 数轴

  • 数轴(Number Line): 数轴是一个水平直线,通常从左到右排列,代表了所有实数的有序集合。零位于数轴的中心,正数在右侧,负数在左侧。

# 3. 相反数

  • 相反数(Opposite or Additive Inverse): 一个数的相反数是与它在数轴上对称的数。例如,对于任何实数 x,其相反数为-x,而-x 的相反数为 x。

# 4. 数学运算

  • 加法: 正数与正数相加,结果仍然是正数;负数与负数相加,结果仍然是负数;正数与负数相加,结果可能是正数、负数或零,取决于它们的相对大小。

  • 减法: 减去一个正数相当于加上它的相反数;减去一个负数相当于加上它的相反数;负数减去正数,结果为负数。

  • 乘法: 两个正数相乘,结果为正数;两个负数相乘,结果为正数;正数与负数相乘,结果为负数。

  • 除法: 正数除以正数,结果为正数;负数除以负数,结果为正数;正数除以负数,结果为负数。

# 5. 应用

  • 方向与位移: 在物理学和工程学中,正数和负数可用于描述方向和位移,其中正方向通常表示向右或向上,而负方向表示向左或向下。

  • 温度: 温度的正负号表示相对于冰点的温度高低,正数表示高于冰点,负数表示低于冰点。

  • 财务: 正数通常表示收入、盈利等正面变化,而负数表示支出、亏损等负面变化。

上次更新: 2024-10-19 10:01:51