信奥AC之路-1级
-
第1课 开发环境与基础输出5 主题|小节
-
第2课 算术运算符7 主题|小节
-
第3课 printf与运算输出7 主题|小节
-
第4课 数的进制与拆位6 主题|小节
-
第5课 变量与基础运算17 主题|小节
-
第6课 常量与取整运算8 主题|小节
-
第7课 关系运算8 主题|小节
-
第8课 逻辑运算9 主题|小节
-
第9课 输入与计算进阶10 主题|小节
-
第10课 if语句及双分支语句8 主题|小节
-
第11课 if语句及双分支进阶11 主题|小节
-
第12课 三目运算9 主题|小节
-
第13课 多分支、多if和switch语句11 主题|小节
-
第14课 循环(基本输出)7 主题|小节
-
第15课 循环(While+If)8 主题|小节
-
第16课 循环(计数、求和、求乘积)10 主题|小节
-
第17课 循环进阶(While+)8 主题|小节
-
第18课 do-while及while其他用法8 主题|小节
-
第19课 For循环基础9 主题|小节
-
第20课 For循环进阶8 主题|小节
选择题
第 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
解题思路
- 读取正整数 a
- 从 1 到 a 遍历,检查每个整数 i 是否为 a 的因数
- 如果 a % i == 0,则 i 是 a 的因数,将其输出
- 按从小到大的顺序输出所有因数
代码实现
#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
解题思路
- 读取整数N和M
- 从1到N遍历每个整数
- 对于每个整数i,检查i是否不是M的倍数(i % M != 0)
- 如果i不是M的倍数,则输出i
- 按顺序输出所有符合条件的数
代码实现
#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。
解题思路
- 读取整数k、L和R
- 定义变量sum用于统计结果
- 从L到R遍历每个整数n
- 对于每个整数n,检查它是否满足幸运数条件:
- 能被k整除 (n % k == 0)
- 或个位数等于k (n % 10 == k)
- 如果满足条件,则sum增加n的值
- 输出最终的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
解题思路
- 读取正整数n
- 定义变量sum用于存储累加结果
- 对于每个i从1到n:
- 计算从1到i的和:1+2+…+i
- 将这个和累加到总和sum中
- 输出最终的累加结果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。
解题思路
- 读取整数A,表示长方形面积
- 设定一个计数器cnt,初始化为0
- 遍历所有可能的长i,从1到sqrt(A):
- 如果A能被i整除,则存在一个宽j = A/i,使得i*j = A
- 此时,增加计数器cnt
- 输出最终的计数结果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的长方形被视为不同长方形
- 对于完全平方数的特殊处理:它们只有一种可能的长宽组合(相等的长和宽)