15.2.1 实验一:输出1~n中所有的偶数
题目描述: 输入一个正整数n,输出从1到n中所有的偶数。
样例输入:
10
样例输出:
2 4 6 8 10
代码实现:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int i = 1; // 初始化循环变量
while(i <= n) { // 循环条件:i不超过n
if(i % 2 == 0) { // 条件判断:i是否为偶数
cout << i << " "; // 如果是偶数则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 筛选条件:
i % 2 == 0(i能被2整除) - 优化方法:从2开始,步长设为2,这样就不需要if判断了
优化后的代码:
#include <iostream>
using namespace std;
int main() {
int n;
cin >> n;
int i = 2; // 从2开始(第一个偶数)
while(i <= n) { // 循环条件:i不超过n
cout << i << " "; // 直接输出i(因为i肯定是偶数)
i += 2; // 步长为2,确保i始终为偶数
}
return 0;
}
15.2.2 实验二:输出m~n中所有的奇数
题目描述: 输入两个正整数m和n (m <= n),输出m到n之间的所有奇数。
样例输入:
4 15
样例输出:
5 7 9 11 13 15
代码实现:
#include <iostream>
using namespace std;
int main() {
int m, n; // 定义范围变量
cin >> m >> n; // 读取范围
int i = m; // 从m开始
while(i <= n) { // 循环条件:i不超过n
if(i % 2 != 0) { // 条件判断:i是否为奇数
cout << i << " "; // 如果是奇数则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 筛选条件:
i % 2 != 0(i不能被2整除,即奇数) - 优化方法:先确定起始的奇数,然后每次加2
优化后的代码:
#include <iostream>
using namespace std;
int main() {
int m, n; // 定义范围变量
cin >> m >> n; // 读取范围
int i = m; // 从m开始
if(i % 2 == 0) { // 如果m是偶数
i++; // 将i调整为下一个奇数
}
while(i <= n) { // 循环条件:i不超过n
cout << i << " "; // 直接输出i(因为i肯定是奇数)
i += 2; // 步长为2,确保i始终为奇数
}
return 0;
}
15.2.3 实验三:输出1~n中是2的倍数,但不是3的倍数的数
题目描述: 输入一个正整数n,输出1到n中所有是2的倍数但不是3的倍数的数。
样例输入:
20
样例输出:
2 4 8 10 14 16 20
代码实现:
#include <iostream>
using namespace std;
int main() {
int n; // 定义范围上限
cin >> n; // 读取范围上限
int i = 1; // 从1开始
while(i <= n) { // 循环条件:i不超过n
// 条件判断:i是2的倍数但不是3的倍数
if(i % 2 == 0 && i % 3 != 0) {
cout << i << " "; // 满足条件则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 复合条件:
i % 2 == 0 && i % 3 != 0(i是2的倍数同时不是3的倍数) - 从数学角度,这相当于找出不是3的倍数的偶数
15.2.4 实验四:输出m-n中能同时满足用3除余2,用5除余3,用7除余2的所有整数
题目描述: 输入两个正整数m和n (m <= n),找出m到n之间能同时满足用3除余2,用5除余3,用7除余2的所有整数。
样例输入:
10 100
样例输出:
23 58 93
代码实现:
#include <iostream>
using namespace std;
int main() {
int m, n; // 定义范围变量
cin >> m >> n; // 读取范围
int i = m; // 从m开始
while(i <= n) { // 循环条件:i不超过n
// 条件判断:同时满足三个取余条件
if(i % 3 == 2 && i % 5 == 3 && i % 7 == 2) {
cout << i << " "; // 满足条件则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 多重条件:需要同时满足三个取余条件
- 数学规律:这类满足多余数条件的数具有周期性
15.2.5 实验五:满足特定规则的两位数
题目描述: 找出所有满足以下条件的两位数:十位上的数字比个位上的数字大,且十位和个位上的数字之和为偶数。
样例输出:
10 12 14 16 18 20 21 23 25 27 29 30 32 34 36 38 41 43 45 47 49 50 52 54 56 58 61 63 65 67 69 70 72 74 76 78 81 83 85 87 89 90 92 94 96 98
代码实现:
#include <iostream>
using namespace std;
int main() {
int i = 10; // 从10开始(第一个两位数)
while(i <= 99) { // 两位数范围:10-99
int shi = i / 10; // 取出十位数字
int ge = i % 10; // 取出个位数字
// 条件判断:十位大于个位,且数位和为偶数
if(shi > ge && (shi + ge) % 2 == 0) {
cout << i << " "; // 满足条件则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 提取数位:使用整除和取余操作提取十位和个位
- 两个条件:十位大于个位,十位和个位之和为偶数
- 范围筛选:两位数范围是10-99
15.2.6 实验六:输出两位的”巧数”
题目描述: 巧数指的是这样一种两位数,该数的各个位数字之和加上各个位数字之积等于本身。比如整数19,就是一个巧数,因为(1+9)+(1*9) = 10 + 9 = 19。输出所有的两位”巧数”。
样例输出:
19 29 39 49 59 69 79 89 99
代码实现:
#include <iostream>
using namespace std;
int main() {
int i = 10; // 从10开始(第一个两位数)
while(i <= 99) { // 两位数范围:10-99
int shi = i / 10; // 取出十位数字
int ge = i % 10; // 取出个位数字
int he = shi + ge; // 计算数位之和
int ji = shi * ge; // 计算数位之积
int result = he + ji; // 计算和与积的和
// 判断是否为巧数:和与积之和等于原数
if(result == i) {
cout << i << " "; // 是巧数则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 巧数的定义:数位之和加上数位之积等于原数本身
- 计算方法:分别计算数位之和和数位之积,然后求和比较
- 两位数范围:10-99
15.2.7 实验七:满足特定规则的三位数
题目描述: 找出所有满足以下条件的三位数:百位、十位、个位的数字之和为偶数,且百位大于十位,十位大于个位。
样例输出:(部分结果)
210 310 320 410 420 430 ...
代码实现:
#include <iostream>
using namespace std;
int main() {
int i = 100; // 从100开始(第一个三位数)
while(i <= 999) { // 三位数范围:100-999
int bai = i / 100; // 取出百位数字
int shi = (i / 10) % 10; // 取出十位数字
int ge = i % 10; // 取出个位数字
// 条件判断:百位>十位>个位,且数位和为偶数
if(bai > shi && shi > ge && (bai + shi + ge) % 2 == 0) {
cout << i << " "; // 满足条件则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 提取数位:需要提取百位、十位和个位
- 多条件判断:百位>十位>个位,且数位和为偶数
- 三位数范围:100-999
15.2.8 实验八:输出所有的”山形数”
题目描述: “山形数”是指一个三位数,其中十位数字大于百位数字且大于个位数字(类似”山”的形状)。输出所有的山形数。
样例输出:(部分结果)
121 131 141 151 ... 292 393 494 595 696 797 898 999
代码实现:
#include <iostream>
using namespace std;
int main() {
int i = 100; // 从100开始(第一个三位数)
while(i <= 999) { // 三位数范围:100-999
int bai = i / 100; // 取出百位数字
int shi = (i / 10) % 10; // 取出十位数字
int ge = i % 10; // 取出个位数字
// 判断十位是否大于百位和个位(山形特征)
if(shi > bai && shi > ge) {
cout << i << " "; // 是山形数则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 山形特征:十位大于百位且大于个位,形成”山”的形状
- 数字提取:使用整除和取余运算提取各个位上的数字
- 三位数范围:100-999
15.2.9 实验九:特殊条件的四位数
题目描述: 找出所有满足以下条件的四位数:千位和百位之和为偶数,十位和个位之和为奇数,且前两位之和大于后两位之和,且含有因数8(能被8整除)。
样例输出:(部分结果)
1024 1032 1048 1056 1072 ...
代码实现:
#include <iostream>
using namespace std;
int main() {
int i = 1000; // 从1000开始(第一个四位数)
while(i <= 9999) { // 四位数范围:1000-9999
int qian = i / 1000; // 取出千位数字
int bai = (i / 100) % 10; // 取出百位数字
int shi = (i / 10) % 10; // 取出十位数字
int ge = i % 10; // 取出个位数字
// 判断各条件
bool c1 = (qian + bai) % 2 == 0; // 千位和百位之和为偶数
bool c2 = (shi + ge) % 2 != 0; // 十位和个位之和为奇数
bool c3 = (qian + bai) > (shi + ge); // 前两位之和大于后两位之和
bool c4 = i % 8 == 0; // 是8的倍数
// 综合判断所有条件
if(c1 && c2 && c3 && c4) {
cout << i << " "; // 满足所有条件则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 多条件组合:需要同时满足4个条件
- 优化方法:可以从8的倍数开始,步长为8,减少循环次数
15.2.10 实验十:包含特定数字且满足条件的整数
题目描述: 输出1-n中含有数字3或者含有数字5,且能被2整除的所有整数。(n<1000)
样例输入:
100
样例输出:
30 32 34 36 38 50 52 54 56 58 ...
代码实现:
#include <iostream>
using namespace std;
int main() {
int n; // 定义范围上限
cin >> n; // 读取范围上限
int i = 1; // 从1开始
while(i <= n) { // 循环条件:i不超过n
// 拆分数位
int ge = i % 10; // 个位
int shi = (i / 10) % 10; // 十位
int bai = i / 100; // 百位
// 判断是否包含数字3或5,且是偶数
if((ge == 3 || ge == 5 || shi == 3 || shi == 5 || bai == 3 || bai == 5) && (i % 2 == 0)) {
cout << i << " "; // 输出满足条件的数
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 数字包含判断:需要逐位检查数字是否包含3或5
- 偶数判断:通过i % 2 == 0判断
- 条件组合:同时满足包含特定数字和能被2整除
15.2.11 实验十一:输出1~999中与7无关的数
题目描述: 如果一个正整数不含有数字7,也不是7的倍数,则称这个数与7无关。输出1到999中所有与7无关的数。
样例输出:(部分结果)
1 2 3 4 5 6 8 9 10 11 12 13 15 16 ...
代码实现:
#include <iostream>
using namespace std;
int main() {
int i = 1; // 从1开始
while(i <= 999) { // 范围:1-999
// 拆分数位
int ge = i % 10; // 个位
int shi = (i / 10) % 10; // 十位
int bai = i / 100; // 百位
// 判断是否与7无关:不包含数字7且不是7的倍数
if((ge != 7 && shi != 7 && bai != 7) && (i % 7 != 0)) {
cout << i << " "; // 输出与7无关的数
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 与7无关:不含有数字7且不是7的倍数
- 判断方法:先检查是否是7的倍数,再检查是否包含数字7
- 范围:1-999
15.2.12 实验十二:输出”特殊尾数”的数
题目描述: “特殊尾数”是指个位数为6或8的数。输入一个正整数n,输出1到n中所有”特殊尾数”的数。
样例输入:
30
样例输出:
6 8 16 18 26 28
代码实现:
#include <iostream>
using namespace std;
int main() {
int n; // 定义范围上限
cin >> n; // 读取范围上限
int i = 1; // 从1开始
while(i <= n) { // 循环条件:i不超过n
int ge = i % 10; // 取出个位数字
// 判断个位是否为6或8
if(ge == 6 || ge == 8) {
cout << i << " "; // 是特殊尾数则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 个位判断:使用
i % 10获取个位数字 - 特殊尾数:个位为6或8的数
15.2.13 实验十三:输出n的所有因数
题目描述: 输入一个正整数n,输出n的所有因数(即能整除n的数)。
样例输入:
12
样例输出:
1 2 3 4 6 12
代码实现:
#include <iostream>
using namespace std;
int main() {
int n; // 定义目标数
cin >> n; // 读取目标数
int i = 1; // 从1开始检查
while(i <= n) { // 循环条件:i不超过n
// 判断i是否为n的因数
if(n % i == 0) {
cout << i << " "; // 是n的因数则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 因数判断:使用
n % i == 0判断i是否是n的因数 - 遍历范围:从1到n
15.2.14 实验十四:输出m~n中特殊条件的数
题目描述: 输入两个正整数m和n (m <= n),输出m到n之间所有个位是k或者是k的倍数的数。
样例输入:
10 30
7
样例输出:
14 17 21 27 28
代码实现:
#include <iostream>
using namespace std;
int main() {
int m, n; // 定义范围变量
cin >> m >> n; // 读取范围
int i = m; // 从m开始
while(i <= n) { // 循环条件:i不超过n
int ge = i % 10; // 取出个位数字
// 判断个位是7或者是7的倍数
if(ge == k || i % k == 0) {
cout << i << " "; // 满足条件则输出
}
i++; // 更新循环变量
}
return 0;
}
思考:
- 双条件判断:个位是k或者是k的倍数
- 注意:这两个条件使用逻辑或(
||)连接
15.2.15 实验十五:长方形面积计算实验
题目描述: 输入一个正整数n代表长方形的面积,请输出所有可能的长方形的宽和长(均为正整数)。长和宽按照从小到大的顺序输出,宽不大于长(即考虑宽≤长的所有可能性,包括正方形)。
样例输入:
16
样例输出:
1 16
2 8
4 4
代码实现:
// 长方形的面积是n,输出所有可能的宽和长
#include <iostream>
using namespace std;
int main() {
int n; // n代表长方形的面积
cin >> n;
int i = 1; // i代表长方形的宽,宽最小是1
while(i <= n/i) { // 宽<=长,长=面积/宽
if(n % i == 0) {
cout << i << " " << n/i << endl;
}
i++;
}
return 0;
}
思考:
- 这个算法为什么限制i ≤ n/i?这是为了确保宽不大于长,避免重复输出
- 如果长方形的面积是16,符合条件的宽和长有:1×16、2×8、4×4
- 时间复杂度分析:该算法只需遍历到宽度等于√n,效率较高
15.2.16 实验十六: 闰年判断实验
题目描述: 输入两个正整数s和e(s < e),输出s年到e年之间所有的闰年(不包含s年和e年)。一行输出一个闰年。闰年的判断规则:能被4整除但不能被100整除,或者能被400整除的年份是闰年。
样例输入:
2000 2020
样例输出:
2004
2008
2012
2016
代码实现:
// 输出s年到e年之间所有的闰年
#include <iostream>
using namespace std;
int main() {
int s, e;
cin >> s >> e;
int i = s + 1;
while(i < e) {
if((i % 4 == 0 && i % 100 != 0) || i % 400 == 0) {
cout << i << endl;
}
i++;
}
return 0;
}
思考:
- 闰年的判断规则:
- 能被4整除但不能被100整除的年份是闰年
- 能被400整除的年份也是闰年
- 逻辑运算符优先级:
&&的优先级高于||,所以i % 4 == 0 && i % 100 != 0会先执行 - 为什么从s+1开始到e-1结束?题目要求不包含s年和e年
- 历史知识:闰年的设计是为了弥补地球公转一周与日历年之间的差异