返回 课程

信奥AC之路-1级

0% 完成
0/0 步骤
  1. 第1课 开发环境与基础输出
    5 主题|小节
  2. 第2课 算术运算符
    7 主题|小节
  3. 第3课 printf与运算输出
    7 主题|小节
  4. 第4课 数的进制与拆位
    6 主题|小节
  5. 第5课 变量与基础运算
    17 主题|小节
  6. 第6课 常量与取整运算
    8 主题|小节
  7. 第7课 关系运算
    8 主题|小节
  8. 第8课 逻辑运算
    9 主题|小节
  9. 第9课 输入与计算进阶
    10 主题|小节
  10. 第10课 if语句及双分支语句
    8 主题|小节
  11. 第11课 if语句及双分支进阶
    11 主题|小节
  12. 第12课 三目运算
    9 主题|小节
  13. 第13课 多分支、多if和switch语句
    11 主题|小节
  14. 第14课 循环(基本输出)
    7 主题|小节
  15. 第15课 循环(While+If)
    8 主题|小节
  16. 第16课 循环(计数、求和、求乘积)
    7 主题|小节
  17. 第17课 循环进阶(While+)
  18. 第18课 do-while及while其他用法
  19. 第19课 For循环基础
  20. 第20课 For循环进阶
课 15, 主题|小节 3
进行中

15.2 实验与应用

2025年12月1日
课 进展
0% 完成

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;
}

思考

  1. 筛选条件:i % 2 == 0(i能被2整除)
  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;
}

思考

  1. 筛选条件:i % 2 != 0(i不能被2整除,即奇数)
  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;
}

思考

  1. 复合条件:i % 2 == 0 && i % 3 != 0(i是2的倍数同时不是3的倍数)
  2. 从数学角度,这相当于找出不是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;
}

思考

  1. 多重条件:需要同时满足三个取余条件
  2. 数学规律:这类满足多余数条件的数具有周期性

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;
}

思考

  1. 提取数位:使用整除和取余操作提取十位和个位
  2. 两个条件:十位大于个位,十位和个位之和为偶数
  3. 范围筛选:两位数范围是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;
}

思考

  1. 巧数的定义:数位之和加上数位之积等于原数本身
  2. 计算方法:分别计算数位之和和数位之积,然后求和比较
  3. 两位数范围: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;
}

思考

  1. 提取数位:需要提取百位、十位和个位
  2. 多条件判断:百位>十位>个位,且数位和为偶数
  3. 三位数范围: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;
}

思考

  1. 山形特征:十位大于百位且大于个位,形成”山”的形状
  2. 数字提取:使用整除和取余运算提取各个位上的数字
  3. 三位数范围: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;
}

思考

  1. 多条件组合:需要同时满足4个条件
  2. 优化方法:可以从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;
}

思考

  1. 数字包含判断:需要逐位检查数字是否包含3或5
  2. 偶数判断:通过i % 2 == 0判断
  3. 条件组合:同时满足包含特定数字和能被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;
}

思考

  1. 与7无关:不含有数字7且不是7的倍数
  2. 判断方法:先检查是否是7的倍数,再检查是否包含数字7
  3. 范围: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;
}

思考

  1. 个位判断:使用i % 10获取个位数字
  2. 特殊尾数:个位为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;
}

思考

  1. 因数判断:使用n % i == 0判断i是否是n的因数
  2. 遍历范围:从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;
}

思考

  1. 双条件判断:个位是k或者是k的倍数
  2. 注意:这两个条件使用逻辑或(||)连接

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;
}

思考

  1. 这个算法为什么限制i ≤ n/i?这是为了确保宽不大于长,避免重复输出
  2. 如果长方形的面积是16,符合条件的宽和长有:1×16、2×8、4×4
  3. 时间复杂度分析:该算法只需遍历到宽度等于√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;
}

思考

  1. 闰年的判断规则:
    • 能被4整除但不能被100整除的年份是闰年
    • 能被400整除的年份也是闰年
  2. 逻辑运算符优先级:&&的优先级高于||,所以i % 4 == 0 && i % 100 != 0会先执行
  3. 为什么从s+1开始到e-1结束?题目要求不包含s年和e年
  4. 历史知识:闰年的设计是为了弥补地球公转一周与日历年之间的差异