CCF认证CSP-J入门组模拟测试题
二、阅读程序题
(程序输入不超过数组或字符串定义的范围;除特殊说明外,判断题 1.5分,选择题3分,共计40分)
第一题
1 #include<iostream>
2 using namespace std;
3 int a,b,c;
4 int main()
5 {
6 cin>>a>>b>>c;
7 a = b - a;
8 b = b - a;
9 a = b + a;
10 c = b - a;
11 cout<<a<<" "<<b<<" "<<c;
12 return 0;
13 }
程序分析
这段程序是一个简单的C++程序,它接收三个整数作为输入,并通过一系列的数学运算重新排列这三个数,最后输出这三个数的新值。从数学上看,这个程序的目的是将输入的三个数(a, b, c)重新排列为(b-a, b-a, b-2a)。
判断题
1)、若输入1 2 3,则输出3 2 1
2)、若输入123456789012 2 3,将输出2 123456789012 123456789010
3)、该程序中,头文件#include<iostream>可以改成#include<cstdio>
4)、若输入10,20,30(逗号隔开),符合程序的输入要求
答案:1× 2 × 3 × 4 ×
答案分析:
1、从程序分析可以得出输入1 2 3,输出的结果应该是2 1 -1,所以错误
2、输入123456789012,这个超出的int类型的范围,所以错误
3、程序中的cin和cout语句都需要用到iostream,所以不能更改,答案错误
4、cin默认是以空格或者换行符隔开,所以用逗号隔开不符合要求,答案错误
单选题
5)、若输入10 20 30 ,输出
A、20 10 20
B、20 10 10
C、20 10 30
D、20 10 -10
答案:D
答案分析:输入的是10 20 30 ,计算过程如下:
a = b - a = 20 - 10 = 10
b = b - a = 20 - 10 = 10
a = b + a = 10 + 10 = 20
c = b - a = 10 - 20 = -10
s所以最后a = 20,b = 10 ,c = -10,答案D
6)、若将第10行的c = a - b 改成 c = b,则输入3 6 9,输出
A、6 3 6
B、6 3 9
C、6 3 3
D、3 6 3
答案:C
答案分析:分析计算过程如上,最后得到的结果应该是6 3 3 ,答案C
第二题
1 #include <cstdio>
2 bool pd(long long n)
3 {
4 if(n==1)
5 return false;
6 for(long long i=2;i<n;i++)
7 if(n%i == 0) return false;
8 return true;
9 }
10 int main()
11 {
12 long long n,i,c=0;
13 int INF = 1 << 30;
14 scanf("%d",&n);
15 for(i=2;i<=INF;i++)
16 {
17 if(pd(i))
18 {
19 c++;
20 if(c==n)
21 {
22 printf("%d",i);
23 return 0;
24 }
25 }
26 }
27 printf("\nover");
28 return 0;
29 }
程序分析
该段代码要实现的功能是计算第n个质数。程序定义了一个名为pd的函数,该函数用于判断一个给定的长整型数n是否为质数。然后在main函数中,程序从2开始逐一检查每个数字,直到找到第n个质数为止。
判断题
1)、上述代码中,若将第13行修改为INF=1<<40,则输出结果一定不变。
2)、上述代码中,将第23行修改为break或continue这两种情况后,有相同的输人,在这两种情况下,输出结果也一定相同。
3)、上述代码中,将第23行修改为break后,有相同的输入,变量c的值和未修改前一定相同。
4)、上述代码中,将第 23行修改为break后,有相同的输入,输出结果也一定相同。
答案:1 × 2 √ 3 √ 4 ×
答案分析:
1、修改为INF=1<<40,超出了int范围,答案错误
2、程序分析已经很清楚是求第n个质数,所以第23行return 0换成break和continue结果都是一样,答案正确
3、分析和第2题一样
4、如果改成break,会多输出一行over,答案错误
单选题
5)、 输人为:8,输出为
A、17
B、19回车over
C、19
D、23\nover
答案:C
答案分析:第8个质数就是19,答案C
5)、上述代码中,将第6行的i<n 修改为()后功能不变,效率更高
A、i*i<=n
B、i<n/2
C、i<n/3
D、i<n/4
答案:A
答案分析:假如两个数x和y,他们乘积如果能够等于n,那么两个数中最小的那个一定小于等于,也就是min(x,y)<=,因此循环变量i能取到的最大值为即可,答案A
第三题
1 #include<bits/stdc++.h>
2 using namespace std;
3 int a[100][100];
4 int b[100][100];
5 int f(int m,int n)
6 {
7 if(m<=0 || n<=0)
8 return 0;
9 a[0][0] = b[0][0];
10 for(int i=1;i<n;i++)a[0][i] = a[0][i-1] + b[0][i];
11 for(int i=1;i<m;i++)a[0][i] = a[i-1][0] + b[i][0];
12 for(int i=1;i<m;i++)
13 {
14 for(int j=i;j<n;j++)
15 {
16 a[i][j] = min(a[i-1][j],a[i][j-1]+b[i][j]);
17 }
18 }
19 return a[m-1][n-1];
20 }
21 int main()
22 {
23 int m,n;
24 cin >> m >> n;
25 for(int i=0;i<m;i++)
26 {
27 for(int j=0;j<n;j++)
28 cin>>b[i][j];
29 }
30 cout<<f(m,n);
31 return 0;
32 }
程序分析
这个程序计算了一个给定的m x n矩阵b中从左上角到右下角的最小路径和,其中只能向右或向下移动。这是一个典型的动态规划问题,并且此代码正确地实现了该问题的解决方案。
判斯题
1) 上述代码实现了对一个长度为mxn的二维数组寻找每一行上的最小值进行求和
2) 上述代码如果删除第4行,其他地方的b数组都改成a数组,那么结果不变
答案:1× 2√
答案分析:本见上面程序分析,可知第一题并不是每一行上最小值求和,而是最小路径求和,所以错误;而第二题如果删除第4行并将所有b数组引用更改为a数组引用,结果将保持不变;这样a数组即使输入数组,也是动态规划中的结果数组,所以正确。
单选题
3)若输人数据为:
4 4
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
则输出的结果为
A、28
B、16
C、136
D、46
答案:D
答案分析:输入的是一个4*4的二维数组,如下所示
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
由于程序是求最小路径之和,只能向下或者向右走,所以经过的路径为:1 2 3 4 8 12 16,所以最终和值为46,答案D
4)上述代码的时间复杂度为
A、O(min(m,n))
B、O(2nm+m+n)
C、O(nm)
D、O(2nm)
答案:C
答案分析:因为程序中出现2次嵌套for循环,所以总的时间复杂度是 O(m * n),因为每个位置 (i, j) 只被访问一次。这意味着算法的时间复杂度是线性的,与矩阵的大小(即行数和列数的乘积)成正比,而时间复杂度是不允许出现常数,所以答案C
5)我们将上述算法称为
A、深度搜索
B、广度搜索
C、动态规划
D、贪心算法
答案:C
答案分析:这是一个典型的最小路径和问题的动态规划解法,在这个例子中,动态规划被用来逐步构建到达每个位置的最小路径和,最终得到从左上角到右下角的最小路径和;答案C
6)上述代码若删除第4行,其他地方的b数组都改成a数组,输人数据为:
3 3
1 2 3 4 5 6 7 8 9
则输出的结果为
A、20
B、12
C、11
D、21
答案:D
答案分析:分析和第三题一样,经过的路径为:1 2 3 6 9,所以答案D