Initial commit: C++ courseware
This commit is contained in:
commit
4a4ee7c287
1789 files changed
+373489
No files matched your search
@@ -0,0 +1,399 @@
|
||||
# NOI CSP-J 初赛专项模拟题:程序基本语句
|
||||
|
||||
## 阅读程序 (程序输入不超过数组或字符串定义的范围,判断题正确填√,错误填×)
|
||||
|
||||
### (1)
|
||||
|
||||
```cpp
|
||||
01 #include <iostream>
|
||||
02 using namespace std;
|
||||
03
|
||||
04 int main() {
|
||||
05 int x, y;
|
||||
06 cin >> x >> y;
|
||||
07 int ans = 1;
|
||||
08 for (int i = 1; i <= y; i++) {
|
||||
09 ans = ans * x;
|
||||
10 ans = ans % 10;
|
||||
11 }
|
||||
12 cout << ans << endl;
|
||||
13 return 0;
|
||||
14 }
|
||||
```
|
||||
|
||||
假设输入的 `x`, `y` 均为不超过 100 的正整数,完成下面的判断题和单选题:
|
||||
|
||||
**判断题**
|
||||
|
||||
1. 该程序的功能是计算 的值。( )
|
||||
2. 程序的输出结果一定是一个小于 10 的整数。( )
|
||||
3. 当输入为“2 3”时,输出为“8”。( )
|
||||
|
||||
**单选题**
|
||||
4. 当输入为“12 2”时,输出为( )。
|
||||
A. 2 B. 4 C. 24 D. 144
|
||||
5. 当输入为“2 10”时,输出为( )。
|
||||
A. 2 B. 4 C. 6 D. 8
|
||||
|
||||
---
|
||||
|
||||
### (2)
|
||||
|
||||
```cpp
|
||||
01 #include <iostream>
|
||||
02 using namespace std;
|
||||
03
|
||||
04 int main() {
|
||||
05 int n;
|
||||
06 cin >> n;
|
||||
07 int a[105];
|
||||
08 for(int i = 1; i <= n; i++) {
|
||||
09 cin >> a[i];
|
||||
10 }
|
||||
11 int count = 0;
|
||||
12 for(int i = 1; i <= n; i++) {
|
||||
13 if(a[i] > 0 && a[i] % 2 == 0) {
|
||||
14 count = count + a[i];
|
||||
15 }
|
||||
16 }
|
||||
17 cout << count << endl;
|
||||
18 return 0;
|
||||
19 }
|
||||
|
||||
```
|
||||
|
||||
假设输入的 `n` 为不超过 100 的正整数,数组元素均为 `int` 范围内整数,完成下面的判断题和单选题:
|
||||
|
||||
**判断题**
|
||||
6. 该程序统计的是数组中所有偶数的个数。( )
|
||||
7. 如果数组中所有的数都是负数,输出结果为 0。( )
|
||||
8. 第 13 行的 `a[i] > 0` 条件如果去掉,程序的输出结果对于任何输入都不会改变。( )
|
||||
|
||||
**单选题**
|
||||
9. 当输入 `n=5`,数组元素为 `1 2 3 4 5` 时,输出为( )。
|
||||
A. 2 B. 3 C. 6 D. 9
|
||||
10. 当输入 `n=5`,数组元素为 `-2 -4 2 4 6` 时,输出为( )。
|
||||
A. 12 B. 6 C. 0 D. -6
|
||||
|
||||
---
|
||||
|
||||
### (3)
|
||||
|
||||
```cpp
|
||||
01 #include <iostream>
|
||||
02 #include <string>
|
||||
03 using namespace std;
|
||||
04
|
||||
05 int main() {
|
||||
06 string s;
|
||||
07 cin >> s;
|
||||
08 int len = s.length();
|
||||
09 for (int i = 0; i < len; i++) {
|
||||
10 if (s[i] >= 'a' && s[i] <= 'z') {
|
||||
11 s[i] = s[i] - 32;
|
||||
12 } else if (s[i] >= 'A' && s[i] <= 'Z') {
|
||||
13 s[i] = s[i] + 32;
|
||||
14 }
|
||||
15 }
|
||||
16 cout << s << endl;
|
||||
17 return 0;
|
||||
18 }
|
||||
|
||||
```
|
||||
|
||||
假设输入仅包含英文字母,完成下面的判断题和单选题:
|
||||
|
||||
**判断题**
|
||||
11. 程序执行后,字符串 `s` 的长度可能会发生改变。( )
|
||||
12. 输入 "CSP" 时,输出 "csp"。( )
|
||||
13. 该程序实现了大小写字母互换的功能。( )
|
||||
|
||||
**单选题**
|
||||
14. 当输入 "Hello" 时,输出为( )。
|
||||
A. hello B. HELLO C. hELLO D. Hello
|
||||
15. 已知 'a' 的 ASCII 码是 97,'A' 的 ASCII 码是 65,则第 11 行可以改为 `s[i] = s[i] - 'a' + 'A'`,效果不变。该说法( )。
|
||||
A. 正确 B. 错误 C. 编译错误 D. 运行时错误
|
||||
|
||||
**(4)**
|
||||
|
||||
```cpp
|
||||
01 #include <iostream>
|
||||
02 using namespace std;
|
||||
03
|
||||
04 int f(int n) {
|
||||
05 if (n <= 1) return 1;
|
||||
06 if (n % 2 == 0)
|
||||
07 return f(n / 2) + n;
|
||||
08 else
|
||||
09 return f(n - 1) + 1;
|
||||
10 }
|
||||
11
|
||||
12 int main() {
|
||||
13 int x;
|
||||
14 cin >> x;
|
||||
15 cout << f(x) << endl;
|
||||
16 return 0;
|
||||
17 }
|
||||
|
||||
```
|
||||
|
||||
假设输入的 x 为不超过 1000 的正整数,完成下面的判断题和单选题:
|
||||
|
||||
**判断题**
|
||||
|
||||
1. 当输入 x 为偶数时,函数 `f(x)` 只会进行递归调用,不会增加数值。( )
|
||||
2. 该函数一定会终止,不会出现死循环。( )
|
||||
3. 当输入 5 时,输出结果为 6。( )
|
||||
|
||||
**单选题**
|
||||
4. 当输入 8 时,输出为( )。
|
||||
A. 13 B. 14 C. 15 D. 16
|
||||
5. 当输入 10 时,函数 `f` 被调用的次数(包括 `main` 中的第一次调用)是( )。
|
||||
A. 4 B. 5 C. 6 D. 7
|
||||
|
||||
**(5)**
|
||||
|
||||
```cpp
|
||||
01 #include <iostream>
|
||||
02 using namespace std;
|
||||
03
|
||||
04 int main() {
|
||||
05 int n, m;
|
||||
06 cin >> n >> m;
|
||||
07 int a[20][20];
|
||||
08 for (int i = 0; i < n; i++) {
|
||||
09 for (int j = 0; j < m; j++) {
|
||||
10 if (i == 0 || j == 0)
|
||||
11 a[i][j] = 1;
|
||||
12 else
|
||||
13 a[i][j] = a[i - 1][j] + a[i][j - 1];
|
||||
14 }
|
||||
15 }
|
||||
16 cout << a[n - 1][m - 1] << endl;
|
||||
17 return 0;
|
||||
18 }
|
||||
|
||||
```
|
||||
|
||||
假设输入的 n, m 均为不超过 15 的正整数,完成下面的判断题和单选题:
|
||||
|
||||
**判断题**
|
||||
|
||||
1. 该程序计算的是组合数学中杨辉三角或类似路径计数的问题。( )
|
||||
2. 如果输入 n=1, m=5,输出结果为 5。( )
|
||||
3. 无论输入什么正整数,数组 `a` 中的值都会随 `i` 和 `j` 的增大而单调递增(不考虑边界)。( )
|
||||
|
||||
**单选题**
|
||||
4. 当输入 3 3 时,输出为( )。
|
||||
A. 4 B. 5 C. 6 D. 10
|
||||
5. 该程序模拟的计算过程等价于求解从网格左上角 (0,0) 走到右下角 (n-1, m-1) 的路径数,且每次只能向右或向下走。如果输入 4 3,输出结果为( )。
|
||||
A. 6 B. 10 C. 15 D. 20
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 三、完善程序 (单选题)
|
||||
|
||||
### (1) 判断回文数
|
||||
|
||||
读入一个正整数 `n`,判断它是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都一样的整数,例如 121 是回文数,而 123 不是。
|
||||
|
||||
```cpp
|
||||
01 #include <iostream>
|
||||
02 using namespace std;
|
||||
03
|
||||
04 int main() {
|
||||
05 int n, t, y = 0;
|
||||
06 cin >> n;
|
||||
07 t = ①;
|
||||
08 while (t > 0) {
|
||||
09 y = y * 10 + ②;
|
||||
10 t = ③;
|
||||
11 }
|
||||
12 if (④)
|
||||
13 cout << "Yes" << endl;
|
||||
14 else
|
||||
15 cout << "No" << endl;
|
||||
16 return 0;
|
||||
17 }
|
||||
|
||||
```
|
||||
|
||||
16. ①处应填( )
|
||||
A. 0 B. 1 C. n D. -1
|
||||
17. ②处应填( )
|
||||
A. t / 10 B. t % 10 C. n % 10 D. n / 10
|
||||
18. ③处应填( )
|
||||
A. t / 10 B. t % 10 C. t - 1 D. t + 1
|
||||
19. ④处应填( )
|
||||
A. n == t B. n == 0 C. n == y D. y == t
|
||||
20. 如果输入的 `n` 是 `100`,循环结束后 `y` 的值是( )
|
||||
A. 1 B. 0 C. 001 D. 10
|
||||
|
||||
### (2) 最大公约数与最小公倍数
|
||||
|
||||
输入两个正整数 `m` 和 `n`,求它们的最大公约数 (GCD) 和最小公倍数 (LCM)。程序使用辗转相除法(欧几里得算法)的迭代实现。
|
||||
|
||||
```cpp
|
||||
01 #include <iostream>
|
||||
02 using namespace std;
|
||||
03
|
||||
04 int main() {
|
||||
05 int m, n, a, b, r;
|
||||
06 cin >> m >> n;
|
||||
07 a = m;
|
||||
08 b = n;
|
||||
09 while (①) {
|
||||
10 r = m % n;
|
||||
11 m = ②;
|
||||
12 n = ③;
|
||||
13 }
|
||||
14 cout << "GCD: " << ④ << endl;
|
||||
15 cout << "LCM: " << ⑤ << endl;
|
||||
16 return 0;
|
||||
17 }
|
||||
|
||||
```
|
||||
|
||||
21. ①处应填( )
|
||||
A. m != 0 B. n != 0 C. r != 0 D. m % n == 0
|
||||
22. ②处应填( )
|
||||
A. n B. r C. a D. b
|
||||
23. ③处应填( )
|
||||
A. m B. r C. a D. b
|
||||
24. ④处应填( )
|
||||
A. n B. r C. m D. a
|
||||
25. ⑤处应填( )
|
||||
A. a * b / m B. a * b / n C. a * b / r D. m * n / a
|
||||
|
||||
---
|
||||
|
||||
**(3) 高精度加法**
|
||||
输入两个正整数(可能非常大,超过 `long long` 范围),输出它们的和。
|
||||
程序使用字符串读取输入,然后转化为数组进行逐位计算。
|
||||
|
||||
```cpp
|
||||
01 #include <iostream>
|
||||
02 #include <string>
|
||||
03 #include <algorithm>
|
||||
04 using namespace std;
|
||||
05
|
||||
06 int a[505], b[505], c[505];
|
||||
07
|
||||
08 int main() {
|
||||
09 string s1, s2;
|
||||
10 cin >> s1 >> s2;
|
||||
11 int len1 = s1.length();
|
||||
12 int len2 = s2.length();
|
||||
13
|
||||
14 for (int i = 0; i < len1; i++) a[len1 - 1 - i] = ①;
|
||||
15 for (int i = 0; i < len2; i++) b[len2 - 1 - i] = s2[i] - '0';
|
||||
16
|
||||
17 int len = len1 > len2 ? len1 : len2;
|
||||
18 for (int i = 0; i < len; i++) {
|
||||
19 c[i] += a[i] + b[i];
|
||||
20 c[i + 1] = ②;
|
||||
21 c[i] = ③;
|
||||
22 }
|
||||
23
|
||||
24 if (④) len++;
|
||||
25
|
||||
26 for (int i = len - 1; i >= 0; i--) {
|
||||
27 cout << ⑤;
|
||||
28 }
|
||||
29 cout << endl;
|
||||
30 return 0;
|
||||
31 }
|
||||
|
||||
```
|
||||
|
||||
26. ①处应填( )
|
||||
A. `s1[i]` B. `s1[i] - '0'` C. `s1[len1 - 1 - i]` D. `s1[len1 - 1 - i] - '0'`
|
||||
27. ②处应填( )
|
||||
A. `c[i] % 10` B. `c[i] / 10` C. `c[i+1] + c[i] / 10` D. `a[i] + b[i]`
|
||||
28. ③处应填( )
|
||||
A. `c[i] / 10` B. `c[i] % 10` C. `a[i] % 10` D. `b[i] % 10`
|
||||
29. ④处应填( )
|
||||
A. `c[len] > 0` B. `c[len] >= 10` C. `c[len-1] > 0` D. `c[len] != 0`
|
||||
30. ⑤处应填( )
|
||||
A. `c[i]` B. `c[len - i]` C. `a[i] + b[i]` D. `c[i] + '0'`
|
||||
|
||||
# 答案与解析
|
||||
|
||||
## 阅读程序
|
||||
|
||||
### (1)
|
||||
|
||||
1. **×**
|
||||
**解析:** 程序在循环中每次将 `ans` 乘以 `x` 后立即对 10 取模,因此它计算的是 的**个位数字**,而不是 的值。
|
||||
2. **√**
|
||||
**解析:** 由于每次运算都执行 `% 10`,结果 `ans` 必定在 0 到 9 之间。
|
||||
3. **√**
|
||||
**解析:** 输入 2 3,循环执行 3 次。
|
||||
```
|
||||
i=1: ans = 1*2%10 = 2
|
||||
i=2: ans = 2*2%10 = 4
|
||||
i=3: ans = 4*2%10 = 8
|
||||
输出 8。
|
||||
```
|
||||
4. **B**
|
||||
**解析:** 输入 12 2。
|
||||
```
|
||||
i=1: ans = 1*12%10 = 12%10 = 2
|
||||
i=2: ans = 2*12%10 = 24%10 = 4
|
||||
输出 4。
|
||||
```
|
||||
5. **B**
|
||||
**解析:** 输入 2 10,计算 的个位数。 规律为 2,4,8,6 循环。10 % 4 = 2,所以是第 2 个,即 4。
|
||||
|
||||
### (2)
|
||||
|
||||
6. **×**
|
||||
**解析:** 变量 `count` 累加的是 `a[i]` 的值(`count = count + a[i]`),而不是个数。它计算的是**大于0的偶数之和**。
|
||||
7. **√**
|
||||
**解析:** 如果全是负数,`a[i] > 0` 条件始终不满足,`count` 保持初始值 0。
|
||||
8. **×**
|
||||
**解析:** 如果去掉 `a[i] > 0`,负偶数也会被加进去,结果会改变。例如输入 -2,原程序加 0,去掉条件后加 -2。
|
||||
9. **C**
|
||||
**解析:** 数组 1 2 3 4 5 中,大于0的偶数有 2, 4。和为 2+4=6。
|
||||
10. **A**
|
||||
**解析:** 数组 -2 -4 2 4 6 中,大于0的偶数有 2, 4, 6。和为 2+4+6=12。
|
||||
|
||||
### (3)
|
||||
|
||||
11. **×**
|
||||
**解析:** 程序只是修改字符的值(ASCII码变换),不涉及插入或删除,长度不变。
|
||||
12. **√**
|
||||
**解析:** C, S, P 都是大写,满足第二个 `if`,加 32 变为小写 c, s, p。
|
||||
13. **√**
|
||||
**解析:** 第一个 `if` 将小写转大写(-32),第二个 `if` 将大写转小写(+32)。
|
||||
14. **C**
|
||||
**解析:** "Hello"。'H' 是大写 -> 'h'。'e','l','l','o' 是小写 -> 'E','L','L','O'。输出 "hELLO"。
|
||||
15. **A**
|
||||
**解析:** `s[i] - 32` 等价于 `s[i] - ('a' - 'A')`,即 `s[i] - 'a' + 'A'`。这是标准的转换方式。
|
||||
|
||||
## 完善程序
|
||||
|
||||
### (1) 判断回文数
|
||||
|
||||
* **算法思路:** 将数字 `n` 翻转生成新数字 `y`,比较 `n` 和 `y` 是否相等。
|
||||
* **解析:**
|
||||
16. **C (n)**:需要用一个临时变量 `t` 来操作,保留原数 `n` 用于最后比较,所以 `t` 初始化为 `n`。
|
||||
17. **B (t % 10)**:取出 `t` 的最后一位数字。
|
||||
18. **A (t / 10)**:去掉 `t` 的最后一位数字,以便下一次循环取下一位。
|
||||
19. **C (n == y)**:比较原数 `n` 和翻转后的数 `y`。
|
||||
20. **A (1)**:`n=100`。
|
||||
第一次:`y=0+0=0`, `t=10`
|
||||
第二次:`y=0+0=0`, `t=1`
|
||||
第三次:`y=0+1=1`, `t=0`
|
||||
循环结束,`y` 为 1。
|
||||
|
||||
### (2) 最大公约数与最小公倍数
|
||||
|
||||
* **算法思路:** 欧几里得算法:`gcd(m, n) = gcd(n, m % n)`,直到 `n` 为 0,此时 `m` 即为 GCD。LCM = (a * b) / GCD。
|
||||
* **解析:**
|
||||
21. **B (n != 0)**:循环继续的条件是除数不为 0。
|
||||
22. **A (n)**:将原来的除数 `n` 赋值给被除数 `m`。
|
||||
23. **B (r)**:将余数 `r` 赋值给除数 `n`。
|
||||
24. **C (m)**:循环结束时 `n` 为 0,`m` 存储的是最大公约数。
|
||||
25. **A (a * b / m)**:最小公倍数 = 两数之积 / 最大公约数。注意原数保存在 `a` 和 `b` 中,`m` 是计算出的 GCD。
|
||||
Reference in new issue
Block a user