阶段小测
此小测全部习题不得使用数组以及函数解答
# 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. 角谷猜想是一种数学猜想,对于任意正整数,如果是奇数,则乘 3
加 1
;如果是偶数,则除以 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. 求 100
到 999
之间的水仙花数。如果一个三位数 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
# 负数的定义:
整数的拓展: 负数的引入是为了扩展整数的概念。在自然数和整数的基础上,引入了负数,使得数学体系更加完备。
小于零的实数: 从数轴的角度来看,负数位于零的左侧。对于实数集合,负数是小于零的实数。
符号表示: 负数通常用负号(-)表示,紧接在一个数值之前,例如-3,-5,-10 等。这个负号表示这个数在数轴上的位置相对于零是在左侧。
相反数: 一个数的相反数是与它在数轴上对称的数。例如,对于任何实数 x,其相反数是-x,而-x 的相反数是 x。相反数的引入使得负数在运算中更加灵活,同时满足加法的封闭性。
# 负数的运算规则:
加法: 负数与负数相加,结果为负数;正数与负数相加,结果可能为正数、负数或零,取决于它们的相对大小。
减法: 减去一个负数相当于加上它的相反数;负数减去正数,结果为负数。
乘法: 两个负数相乘,结果为正数;正数与负数相乘,结果为负数。
除法: 负数除以正数,结果为负数。
# 负数和正数关系
# 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. 应用
方向与位移: 在物理学和工程学中,正数和负数可用于描述方向和位移,其中正方向通常表示向右或向上,而负方向表示向左或向下。
温度: 温度的正负号表示相对于冰点的温度高低,正数表示高于冰点,负数表示低于冰点。
财务: 正数通常表示收入、盈利等正面变化,而负数表示支出、亏损等负面变化。