🎮 C++ 编程小勇士闯关

20道精选关卡,代码已修复完整!
先读题,再思考,最后点按钮看答案哦!✨

LEVEL 1

🌱 入门村:基础运算与变量

1. 整数除法大坑
选择题

在C++中,表达式 5 / 2 的结果是?

  • A) 2.5
  • B) 2
  • C) 3
  • D) 2.0
✅ 正确答案:B

🍪 分饼干图解

🍪🍪🍪🍪🍪 ÷ 👶👶

5块饼干分给2个人,每人分2块。

多出来的1块被“扔掉”了(向下取整)。

解析: C++中整数除以整数,结果必须是整数(自动舍弃小数部分)。

2. 2013年第23题(输出格式)
阅读程序
#include <iostream>
using namespace std;
int main()
{
    int a, b;
    cin >> a >> b; // 输入:3 5
    cout << a << "+" << b << "=" << a + b << endl;
}

输入:3 5,输出结果是?

  • A) 3
  • B) 5
  • C) 8
  • D) 3+5=8
✅ 正确答案:D

解析: 程序像搭积木一样输出:

a(3) + "+" + b(5) + "=" + 结果(8)

拼接起来就是 3+5=8

3. 2012年第23题(简单累加)
阅读程序
#include <iostream>
using namespace std;
int a, b, c, d, e, ans;
int main()
{
    cin >> a >> b >> c; // 输入:1 2 5
    d = a + b;
    e = b + c;
    ans = d + e;
    cout << ans << endl;
    return 0;
}

输出结果是? (A) 3 (B) 7 (C) 10 (D) 编译错误

✅ 正确答案:C

计算步骤:

  • d = 1 + 2 = 3
  • e = 2 + 5 = 7
  • ans = 3 + 7 = 10
4. 2014年第23题(变量覆盖)
顺序结构
#include <iostream>
using namespace std;
int main()
{
 int a, b, c, d, ans;
 cin >> a >> b >> c; // 输入:2 3 4
 d = a - b;
 a = d + c; // 注意!a在这里变身了
 ans = a * b;
 cout << "Ans = " << ans << endl; 
 return(0);
}
✅ 答案:9

📦 变量变化图

a:2
➡️
d:-1
➡️
a:3
(被覆盖)

解析: 1. d = 2 - 3 = -1
2. a = -1 + 4 = 3 (旧值2消失)
3. ans = 3 * 3 = 9

5. 2014年第19题(循环本质)
循环理解
// s, a, b, c 均为整型,c > 0
s = a;   
for(b = 1; b <= c; b++)   
    s += 1;
// 功能等价于?

(A) s=a+b (B) s=a+c (C) s=s+c (D) s=b+c

✅ 正确答案:B

解析: 初始有 a,循环执行了 c 次,每次加 1。相当于一共加了 c。所以 s = a + c。

6. 2019年第4题(循环减法)
循环理解
s = a;
for (b = 1; b <= c; b++) 
    s = s - 1;
// 功能等价于?

(A) s=a-c (B) s=a-b ...

✅ 正确答案:A

解析: 同理,循环 c 次,每次减 1,一共减去 c。结果是 s = a - c。

LEVEL 2

🌲 进阶林:逻辑判断与循环

7. 2015年第23题(Else匹配陷阱)
选择结构
#include <iostream> 
using namespace std;
int main() 
{
    int a, b, c; a = 1; b = 2; c = 3;
    if(a > b)      // 1 > 2 为假
        if(a > c)
            cout << a << ' ';
        else       // 这个else属于内层if
        cout << b << ' '; 
    cout << c << endl; // 这一句一定执行
    return 0;
}
✅ 答案:3

🚧 路线图

if(a > b) 判断为 False

⬇️

跳过整个内部代码块(包括里面的if和else)

⬇️

执行 cout << c

避坑: 缩进是骗人的!else 总是和最近的未匹配 if 结合。

8. 2011年第23题(累加求和)
While循环
#include<iostream>
using namespace std;
int main()
{
    int i,n,m,ans;
    cin>>n>>m; // 输入:10 20
    i=n;
    ans=0;
    while(i<=m){
       ans+=i;
       i++;
    }
    cout<
        
        
✅ 答案:165

解析: 计算 10+11+...+20 的和。

公式:(首项+末项)×项数÷2 = (10+20)×11÷2 = 165。

9. 2014年第13题(浮点数陷阱)
数据类型
#include <iostream>  
using namespace std;  
int main()  
{ 
    int n;     
    float s;     
    s = 1.0; 
    for(n = 10; n > 1; n--)       
        s = s + 1 / n;  // 哪一行代码导致结果错误?
    cout << s << endl;    
    return 0;   
} 

(A) s=1.0 (B) for... (C) s=s+1/n (D) cout...

✅ 正确答案:C

解析: 1n 都是整数。

当 n=10 时,1 / 10 在C++整数运算中等于 0,小数部分被丢弃。

改正: 应写成 1.0 / n

10. 2013年第24题(整除计数)
条件计数
// 输入:1 100 15
for (i = a; i <= b; i++) 
    if ((i % u) == 0)
        num++;

计算 1 到 100 之间能被 15 整除的数有多少个?

✅ 正确答案:C (6个)

列举: 15, 30, 45, 60, 75, 90。

共 6 个。

11. 2014年第15题(倒推法)
Do-While循环
s= 0; a= 1;
do {
  s+= 1;
  a-= 2;
} while ( a != n );

若输出 s=2,则输入 n 应该是多少? (A)-1 (B)-3 (C)-5 (D)0

✅ 正确答案:B (-3)

解析: 输出s=2说明循环了2次。

  • 第1次:s=1, a=1-2 = -1
  • 第2次:s=2, a=-1-2 = -3

循环结束条件是 a==n,所以 n 就是 -3。

LEVEL 3

⛰️ 高手山:复杂逻辑与嵌套

12. 2016年第13题(Continue跳跃)
流程控制
#include <iostream>
using namespace std;
int main()
{
    int k = 4, n = 0;
    while (n < k)
    {
        n++;
        if (n % 3 != 0) // 如果n不是3的倍数
            continue;   // 跳过后面,直接开始下一次循环
        k--;
    }
    cout << k << "," << n << endl;
    return 0;
}
✅ 正确答案:D (3,3)

🏃‍♂️ 循环记录

1. n=1 (跳过 k--) k=4

2. n=2 (跳过 k--) k=4

3. n=3 (是3的倍数! 执行 k--) k=3

判断:n < k? (3 < 3) ➡️ False,结束

13. 2007年第13题(死循环的传说)
概念理解

关于“死循环”,下列说法正确的是:

  • A. 任何编译系统都无法完全检查出死循环
  • B. 编译器能查出来
  • C. 死循环是语法错误
  • D. 类似死锁,可以检测
✅ 正确答案:A

解析: 这是一个著名的计算机原理(停机问题)。电脑无法在运行前百分百预测程序是否会永远停不下来。

14. 2018年第19题(模运算循环)
数学应用
#include 
int main() {
    int x;
    scanf("%d", &x); // 输入:15
    int res = 0;
    for (int i = 0; i < x; ++i) {
        if (i * i % x == 1) {
            ++res;
        }
    }
    printf("%d", res);
    return 0;
}
✅ 答案:4

解析: 寻找 0~14 之间,平方后除以 15 余 1 的数。

  • 1*1 = 1 (余1) ✅
  • 4*4 = 16 (16÷15余1) ✅
  • 11*11 = 121 (121÷15余1) ✅
  • 14*14 = 196 (196÷15余1) ✅
15. 2010年第24题(回文数)
函数逻辑
// rSum函数会将数字反转 (例 123 -> 321)
int main()
{
    int n, m, i;        
    cin>>n>>m; // 输入:90 120
    for (i = n; i < m; i++)
        if (i == rSum(i)) // 如果数字和它的反转相等
           cout<
        
        
✅ 答案:99 101 111

解析: 找 90 到 119 之间的“回文数”。

  • 99 -> 反转还是99 (是)
  • 100 -> 反转是001 (否)
  • 101 -> 反转是101 (是)
  • 111 -> 反转是111 (是)
16. 2010年第23题(交换与排序)
排序逻辑
    cin>>a1>>a2>>a3; // 输入:91 2 20
    // 三次swap交换,其实是在做排序
    if (a1 > a2) swap(a1, a2);
    if (a2 > a3) swap(a2, a3);
    if (a1 > a2) swap(a1, a2);
    // 此时 a1, a2, a3 已经从小到大排好了
    
    cin>>x; // 输入 77
    // 下面的if是在找x应该插在哪里
✅ 答案:A (2 20 77 91)

解析:

1. 排序前三个数:2, 20, 91。

2. 插入 77:它比 20 大,比 91 小。

3. 结果:2, 20, 77, 91。

17. 2012年第24题(找因子)
循环计数
#include 
using namespace std;
int n, i, ans;
int main()
{
    cin >> n; // 输入:18
    ans = 0;
    for (i = 1; i <= n; i++)
        if (n % i == 0) ans++;
    cout << ans << endl;
    return 0;
}

输出结果是? (A) 4 (B) 5 (C) 6 (D) 7

✅ 正确答案:C

解析: 找 18 的所有因数。

1, 2, 3, 6, 9, 18。共 6 个。

18. 2013年第19题(1加到100)
循环控制

哪个程序能正确计算 1+2+...+100?

  • A. i=1; do{ sum+=i; i++; }while(i<=100);
  • B. while(i > 100)
  • C. while(i < 100)
  • D. while(i >= 100)
✅ 正确答案:A

解析: A选项do-while先执行后判断,能覆盖到100。C选项当i=100时就不执行了,会少加一个数。

LEVEL 4

🏰 挑战塔:算法填空 (Boss战)

19. 2020年第19题(质因数分解)
算法填空

功能:输入 120,输出 2 2 2 3 5。
请补全代码:

#include 
using namespace std;
int n, i;
int main() {
    scanf("%d", &n);
    for (i = 【①】; 【②】 <= n; i++) {   
        【③】 {           
            printf("%d ", i);
            n = n / i;               
        }
    }
    if (【④】)                        
        printf("%d ", 【⑤】);            
    return 0;
}

选项参考:①初始值 ②循环条件 ③判断方式 ④剩余判断 ⑤输出剩余

✅ 答案:C C C A C

🔪 切蛋糕算法

1. 从最小质数 2 开始切 (①选C)

2. 只要试到 i*i <= n 就够了 (②选C)

3. 如果能切动,要一直切(用while),比如120含有三个2 (③选C)

4. 最后如果剩下一块 (n > 1),说明剩下的就是个大质数,直接输出 (④⑤)

20. 2022年第19题(枚举因数)
Vector应用
#include 
using namespace std;
int main() {
    int n; cin >> n;
    vector fac;
    // ...省略部分...
    for (i = 1; i * i < n; ++i) {
        if (【①】) {   
            fac.push_back(i);
        }
    }
    // ...输出前半部分...
    // ...输出后半部分...
}

这是一道完善程序题,考察如何高效找出所有因数。

✅ 答案:A B C D A

核心思路: 只找 i * i < n 的小因数(比如36,只找1, 2, 3, 4),存进 vector。

n % i == 0:是因数才存。

大因数可以通过 n / 小因数 算出来。

🎉 恭喜你完成了所有挑战!你是最棒的! 🌟