返回 课程

信奥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课 循环(计数、求和、求乘积)
    10 主题|小节
  17. 第17课 循环进阶(While+)
    8 主题|小节
  18. 第18课 do-while及while其他用法
    8 主题|小节
  19. 第19课 For循环基础
    9 主题|小节
  20. 第20课 For循环进阶
    8 主题|小节
课 进展
0% 完成

选择题

第 1 题

下面的C++代码用于求1-N之间所有奇数之和。其中N为正整数。如果N为奇数,则求和时包括N。有关描述错误的是( )。

int N;
cout << "请输入正整数: ";
cin >> N;
int i = 1, Sum = 0;
while (i <= N){
    if (i % 2 == 1)
        Sum += i;
    i += 1;
}
cout << i << " " << Sum;

□ A. 执行代码时如果输入10,最后一行输出将是 11 25
□ B. 执行代码时如果输入5,最后一行输出将是 6 9
□ C. 将 i += 1 移到 if (i % 2 == 1) 前一行,同样能实现题目要求
□ D. 删除 if (i % 2 == 1) ,并将 i += 1 改为 i += 2 ,同样可以实现题目要求

答案:C. 将 i += 1 移到 if (i % 2 == 1) 前一行,i进了循环直接就变成2了。

解析: 这段代码计算1到N之间所有奇数的和。

选项C描述错误,因为如果将i += 1移到if(i % 2 == 1)前面,变成:

cppCopywhile (i <= N){
    i += 1;
    if (i % 2 == 1)
        Sum += i;
}

这样会导致i从2开始计算,而不是从1开始,会漏掉第一个奇数1。例如输入N=5时,原代码计算1+3+5=9,而修改后计算3+5=8,结果不同。

选项A、B和D的描述都是正确的:

  • 选项A:输入10时,确实输出”11 25″
  • 选项B:输入5时,确实输出”6 9″
  • 选项D:将循环改为从1开始每次加2,确实能正确计算所有奇数之和

因此,选项C是错误的描述,正确答案是C。

第 2 题

下面C++代码执行后的输出是( )。

int N = 10;
while(N){
    N -= 1;
    if(N%3 == 0)
        cout << N << "#";
}

□ A. 9#6#3#
□ B. 9#6#3#0#
□ C. 9#7#6#3#0#
□ D. 10#9#7#6#3#0#

答案:B. 9#6#3#0#

解析:
这段代码先将N减1,然后检查N是否能被3整除,如果能,则输出N和”#”。循环直到N变为0。

执行过程:

  • 初始N=10
  • 第一次循环:N减1变为9,9%3=0,输出”9#”
  • 第二次循环:N减1变为8,8%3≠0,不输出
  • 第三次循环:N减1变为7,7%3≠0,不输出
  • 第四次循环:N减1变为6,6%3=0,输出”6#”
  • 第五次循环:N减1变为5,5%3≠0,不输出
  • 第六次循环:N减1变为4,4%3≠0,不输出
  • 第七次循环:N减1变为3,3%3=0,输出”3#”
  • 第八次循环:N减1变为2,2%3≠0,不输出
  • 第九次循环:N减1变为1,1%3≠0,不输出
  • 第十次循环:N减1变为0,0%3=0,输出”0#”

因此,最终输出是”9#6#3#0#”。

第 3 题

下面C++代码执行后的输出是( )。

int n = 5;
int cnt = 1;
while (n >= 0) {
    cnt += 1;
    n -= 2;
}
cout << cnt;

□ A. 3
□ B. 4
□ C. 6
□ D. 7

答案:B. 4

解析:
这段代码中,n初始值为5,cnt初始值为1。当n大于等于0时,cnt加1,n减2。

循环执行过程:

  • n=5 >= 0,cnt增至2,n减至3
  • n=3 >= 0,cnt增至3,n减至1
  • n=1 >= 0,cnt增至4,n减至-1
  • n=-1 < 0,循环结束

所以,最终cnt的值为4,答案是B。

编程题

编程题1:找因数

问题描述

小A最近刚刚学习了因数的概念。具体来说,如果一个正整数a可以被另一个正整数b整除,那么我们就说b是a的因数。

请你帮写一个程序,从小到大输出正整数a的所有因数。

输入描述

输入一行一个正整数a。保证a ≤ 1,000。

输出描述

输出若干行,为a的所有因数,从小到大排列。

特别提醒

在常规程序中,输入、输出时提供提示是好习惯,但在本场考试中,由于系统限定,请不要在输入、输出中附带任何提示信息。

样例输入1
1
样例输出1
1
样例输入2
6
样例输出2
1
2
3
6
样例输入3
10
样例输出3
1
2
5
10
解题思路
  1. 读取正整数 a
  2. 从 1 到 a 遍历,检查每个整数 i 是否为 a 的因数
  3. 如果 a % i == 0,则 i 是 a 的因数,将其输出
  4. 按从小到大的顺序输出所有因数
代码实现
#include <iostream>
using namespace std;

int main() {
    int a;                      // 定义变量a,存储输入的整数
    cin >> a;                   // 输入整数a
    
    int i = 1;                  // 初始化测试值为1
    while (i <= a) {            // 当i小于等于a时继续循环
        if (a % i == 0) {       // 检查i是否为a的因数
            cout << i << endl;   // 如果是因数,则输出i
        }
        i++;                    // i自增1,测试下一个整数
    }
    
    return 0;
}
代码分析
  • 使用取模运算(%)检查整除性,判断因数关系
  • while循环版本需要手动初始化和递增循环计数器i
  • 输出采用逐行打印方式,每个因数占一行
  • 时间复杂度为O(n),其中n为输入的正整数a
注意事项
  • 循环范围需要包含1和a本身,因为它们都是a的因数
  • 确保按从小到大的顺序输出因数
  • 根据题目要求,不要输出任何提示信息
  • 对于较大的输入值,O(n)的算法可能效率不高
  • 每个因数需要单独占一行输出
关键点
  • 理解因数的定义:b是a的因数当且仅当a能被b整除
  • 使用取模运算符(%)检查整除性
  • 遍历方法的选择(从1到a逐个检查)
  • 输出格式的严格控制
  • 对于特殊输入(如1)的正确处理

编程题2:小杨报数

问题描述

小杨需要从1到N报数。在报数过程中,小杨只报哪些M的倍数。例如,如果N = 5,M = 2,那么小杨就只需要报出1、3、5。

现在,请你代替小杨报数。

输入描述

输入2行,第一行一个整数N(1 ≤ N ≤ 1,000);第二行一个整数M(2 ≤ M ≤ 100)。

输出描述

输出若干行,依次表示小杨的报数。

特别提醒

在常规程序中,输入、输出时提供提示是好习惯,但在本场考试中,由于系统限定,请不要在输入、输出中附带任何提示信息。

样例输入1
5
2
样例输出1
1
3
5
样例输入2
10
3
样例输出2
1
2
4
5
7
8
10
解题思路
  1. 读取整数N和M
  2. 从1到N遍历每个整数
  3. 对于每个整数i,检查i是否不是M的倍数(i % M != 0)
  4. 如果i不是M的倍数,则输出i
  5. 按顺序输出所有符合条件的数
代码实现
#include <stdio.h>

int main(int argc, char **argv) {
    int n, m;                   // 定义变量n和m
    scanf("%d", &n);            // 输入整数n
    scanf("%d", &m);            // 输入整数m
    
    int i = 1;                  // 初始化循环变量为1
    while(i <= n) {             // 当i小于等于n时继续循环
        if(i % m != 0)          // 检查i是否不是m的倍数
            printf("%dn", i);   // 如果不是m的倍数,则输出i
        i++;                    // i自增1
    }
    
    return 0;
}
代码分析
  • 使用条件判断(i % m != 0)筛选需要报出的数字
  • while循环版本需要手动管理循环变量i
  • 使用printf函数输出结果,每个数字占一行
  • 每次判断都是独立的,时间复杂度为O(n)
注意事项
  • 理解”报不是M的倍数”的含义:输出那些不能被M整除的数
  • 确保输出格式正确,每个数字占一行
  • 不要添加任何提示性文字,只输出纯数字
  • 循环范围必须是从1到N
  • 对于大数据量输入,时间复杂度为O(n)
关键点
  • 使用取模运算(%)判断数字是否为另一个数的倍数
  • 理解逻辑:报出的是那些”不是M的倍数”的数
  • 输出格式的控制:每个数字单独占一行
  • 循环边界的设置:从1到N
  • 条件判断的准确性

编程题3:小明的幸运数

问题描述

所有等于k的倍数,或个位数等于k的正整数,都被小明称为”幸运数”。小明想知道正整数L和R之间(包括L和R本身)有多少个幸运数?

输入描述

输入3行,第一行包含一个正整数k,第二行包含一个正整数L,第三行包含一个正整数R。约定2 ≤ k ≤ 9,1 ≤ L ≤ R ≤ 1000。

输出描述

输出1行,为合计数量。

样例输入1
7
1
10
样例输出1
7
样例解释1

10和20之间共有2个幸运数:14和17。14是7的倍数,17个位数为7。因此,结果为31。

样例输入2
7
10
20
样例输出2
31
样例解释2

10和20之间共有2个7幸运数:14和17。14是7的倍数,17个位数为7。因此,结果为31。

解题思路
  1. 读取整数k、L和R
  2. 定义变量sum用于统计结果
  3. 从L到R遍历每个整数n
  4. 对于每个整数n,检查它是否满足幸运数条件:
    • 能被k整除 (n % k == 0)
    • 或个位数等于k (n % 10 == k)
  5. 如果满足条件,则sum增加n的值
  6. 输出最终的sum值
代码实现
#include <iostream>
using namespace std;

int main() {
    int k = 0, L = 0, R = 0, sum = 0;  // 定义变量k、L、R和sum
    cin >> k >> L >> R;                // 输入k、L和R
    
    int n = L;                         // 初始化循环变量n为L
    while (n <= R) {                   // 当n小于等于R时继续循环
        if (n % 10 == k || n % k == 0)  // 检查n是否满足幸运数条件
            sum += n;                   // 如果是幸运数,则累加到总和中
        n++;                           // n自增1
    }
    
    cout << sum << endl;               // 输出幸运数的总和
    return 0;
}
代码分析
  • 使用逻辑或(||)组合两个条件:个位数等于k或能被k整除
  • while循环版本需要手动管理循环变量n
  • 使用取模运算符(%)检查整除性和获取个位数
  • 累加满足条件的数字值,而不是简单地计数
  • 结果为符合条件的所有数字的总和
注意事项
  • 理解幸运数的定义:个位数等于k或能被k整除
  • 计算的是幸运数之和,而不是幸运数的个数
  • 遍历范围包括边界值L和R
  • 使用正确的逻辑或(||)运算符组合条件
  • 变量sum初始化为0,确保累加结果正确
关键点
  • 理解问题要求:计算幸运数之和,不是计数
  • 使用取模运算符(%)获取个位数:n % 10
  • 使用取模判断整除性:n % k == 0
  • 组合多个条件:使用逻辑或(||)连接
  • 确保遍历范围正确:包括边界值L和R

编程题4:累计相加

问题描述

输入一个正整数n,求形如:1 + (1 + 2) + (1 + 2 + 3) + (1 + 2 + 3 + 4) + …(1 + 2 + 3 + 4 + 5 + … + n)的累计相加。

输入描述

输入一个正整数。约定 1 ≤ n ≤ 100。

输出描述

输出累计相加的结果。

样例输入1
3
样例输出1
10
样例输入2
4
样例输出2
20
样例输入3
10
样例输出3
220
解题思路
  1. 读取正整数n
  2. 定义变量sum用于存储累加结果
  3. 对于每个i从1到n:
    • 计算从1到i的和:1+2+…+i
    • 将这个和累加到总和sum中
  4. 输出最终的累加结果sum

公式分析:

  • 1到i的和可以用公式:i * (i + 1) / 2 计算
  • 最终结果是对每个部分和的累加
代码实现
#include <iostream>
using namespace std;

int main() {
    int n = 0;              // 定义变量n
    cin >> n;               // 输入正整数n
    
    int sum = 0;            // 定义变量sum,用于存储最终结果
    
    int i = 1;              // 初始化循环变量i为1
    while (i <= n) {        // 当i小于等于n时继续循环
        sum += (i * (i + 1)) / 2;  // 累加1到i的和:i*(i+1)/2
        i++;                // i自增1
    }
    
    cout << sum << endl;    // 输出累加结果
    return 0;
}
代码分析
  • 使用数学公式i*(i+1)/2计算1到i的和,优化计算效率
  • while循环版本需要手动管理循环变量i
  • 整数除法运算需要注意顺序,以避免精度损失
  • 时间复杂度为O(n),其中n为输入的正整数
注意事项
  • 对于大的n值,需要考虑整数溢出问题
  • 使用数学公式计算部分和,而不是嵌套循环,提高效率
  • 变量sum初始化为0,确保累加结果正确
  • 整数除法可能导致精度损失,但本题中不是问题
  • 确保循环范围正确:从1到n
关键点
  • 理解问题的累加模式:每一项都是从1加到i的和
  • 使用数学公式计算部分和:i*(i+1)/2
  • 高效实现:避免使用嵌套循环,时间复杂度O(n)
  • 整数运算的顺序:先乘后除,以保持精度
  • 对于极限情况(如n=100)的正确处理

编程题5:长方形面积

问题描述

小明刚刚学习了几何计算长方形面积,他发现,如果一个长方形的长和宽都是整数,它的面积一定是整数。那么小明对此产生了一个问题:如果确定长方形的面积,有多少种可能的长方形?

如果两个长方形的长或宽不同,那么就算是不同的长方形。例如,长为2宽为4和长为4宽为2的长方形是不同的长方形。

输入描述

输入一行,包含一个整数A,表示长方形面积。约定2 ≤ A ≤ 1000。

输出描述

输出一行,包含一个整数C,表示符合可能的长方形的数量。

样例1

样例输入1:

4

样例输出1:

2

样例解释1:
2种长方形面积为4:它们的长宽分别为2×2、4×1。

样例2

样例输入2:

6

样例输出2:

2

样例解释2:
2种长方形面积为6:它们的长宽分别为2×3、6×1。

解题思路
  1. 读取整数A,表示长方形面积
  2. 设定一个计数器cnt,初始化为0
  3. 遍历所有可能的长i,从1到sqrt(A):
    • 如果A能被i整除,则存在一个宽j = A/i,使得i*j = A
    • 此时,增加计数器cnt
  4. 输出最终的计数结果cnt
代码实现
#include <iostream>
using namespace std;

int main() {
    int area;               // 定义变量area,表示长方形面积
    cin >> area;            // 输入长方形面积
    
    int cnt = 0;            // 定义计数器cnt,用于统计可能的长方形数量
    
    int w = 1;              // 初始化宽度w为1
    while (w * w <= area) { // 当w的平方小于等于area时继续循环
        if (area % w == 0)  // 检查area是否能被w整除
            cnt++;          // 如果可以整除,则找到一种可能的长方形
        w++;                // w自增1
    }
    
    cout << cnt << endl;    // 输出可能的长方形数量
    return 0;
}
代码分析
  • 计数器cnt记录可能的长方形数量
  • 循环上限设为sqrt(area),避免重复计算
  • 使用取模运算(%)检查area是否能被当前宽度w整除
  • while循环版本需要手动管理循环变量w
  • 时间复杂度为O(sqrt(A)),其中A为输入的面积
注意事项
  • 考虑长方形的对称性:只需检查到sqrt(area)
  • 计数器cnt初始化为0
  • 循环上限为sqrt(area),而不是area本身,提高效率
  • 对于完全平方数,如4、9、16等,计数可能与预期不同
  • 确保取模运算的正确使用:area % w == 0
关键点
  • 理解长方形面积与边长的关系:area = length × width
  • 优化搜索范围:只需遍历到sqrt(area)
  • 使用取模运算检查整除性
  • 理解长为a宽为b和长为b宽为a的长方形被视为不同长方形
  • 对于完全平方数的特殊处理:它们只有一种可能的长宽组合(相等的长和宽)