CCF编程能力等级认证GESP—C++4级—20240629
单选题(每题 2 分,共 30 分)
1、下列代码中,输出结果是( )
#include <iostream>
using namespace std;
int func(int x, int y){
int a = x, b = y;
int t;
t = a;
a = b;
b = t;
cout << a << " " << b << " ";
}
int main() {
int c, d;
c = 12;
d = 24;
func(12, 24);
cout << c << " " << d << endl;
return 0;
}
A.12 24 24 12
B.24 12 12 24
C.12 12 24 24
D.24 24 12 12
正确答案:B
2、下面函数不能正常执行的是()
A.
#include <iostream>
using namespace std;
int func(){
//...
}
int main() {
//...
}
B.
#include <iostream>
using namespace std;
int main() {
func();
}
int func(){
//...
}
C.
#include <iostream>
using namespace std;
int func(){
//...
}
int main() {
func();
}
D.
#include <iostream>
using namespace std;
int func();
int main() {
func();
}
int func(){
//...
}
正确答案:B
3、下面程序输出的是()
#include <iostream>
using namespace std;
int func();
int main() {
int i = 2;
cout << i << endl;
for (int x = 0; x < 1; x++){
int i = 10;
cout << i << endl;
}
i = i + 1;
cout << i << endl;
{
i = i * i;
cout << i << endl;
}
}
A. 2 2 3 9
B. 2 10 3 9
C. 2 10 11 121
D. 2 10 3 100
正确答案:B
4、假设变量 a 的地址是0x6ffe14,下面程序的输出是( )。
#include <iostream>
using namespace std;
int main() {
int *p;
int a = 10;
p = &a;
p++;
cout << p << endl;
}
A. 10
B. 0x6ffe14
C. 0x6ffe15
D. 0x6ffe18
正确答案:D
5、如果下列程序输出的地址是 0x6ffe00 ,则 cout<<a+1<<endl; 输出的是()
#include <iostream>
using namespace std;
int main() {
int a[2][3] = {0};
cout << a + 1<< endl;
}
A. 0x6ffe04
B. 0x6ffe0C
C. 0x6ffe08
D. 0x6ffe00
正确答案:B
6、C++中,关于文件路径说法错误的是()
A. "GESP.txt":指定与当前工作目录中的程序文件相同目录中的 GESP.txt 文件
B. "../data/GESP.txt":指定与当前工作目录中的程序文件上一级目录下的 data 目录中的 GESP.txt 文件
C. "./data/GESP.txt":指定与当前工作目录中的程序文件同级目录下的 data 目录中的 GESP.txt 文件
D. "GESP.txt"是绝对路径
正确答案:D
7、关于直接插入排序,下列说法错误的是()
A. 插入排序的最好情况是数组已经有序,此时只需要进行n - 1次比较,时间复杂度为O(n)
B. 最坏情况是数组逆序排序,此时需要进行n(n - 1)/2次比较以及n - 1次赋值操作(插入)
C. 平均来说插入排序算法的复杂度为O(n^2)
D. 空间复杂度上,直接插入法是就地排序,空间复杂度为O(n)
正确答案:D
8、下列程序横线处,应该输入的是 ( )。
#include <iostream>
using namespace std;
int n, a[10001];
void swap(int &a, int &b){
int t = a;
a = b;
b = t;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = n; i > 1; i--)
for (int j = 1; j < i; j++)
if (a[j] > a[j + 1])
____
for (int i = 1; i <= n; i++)
cout << a[i] << " ";
cout << endl;
}
A. swap(a[j],a[j+1]);
B. swap(a[j-1],a[j]);
C. swap(a[j-1],a[j+1]);
D. swap(&a[j-1],&a[j+1]);
正确答案:A
9、下面关于递推的说法不正确的是( )。
A. 递推表现为自己调用自己
B. 递推是从简单问题出发,一步步的向前发展,最终求得问题。是正向的
C. 递推中,问题的n要求是在计算中确定,不要求计算前就知道n
D. 斐波那契数列可以用递推实现求解
正确答案:A
10、关于几种排序算法的说法,下面说法错误的是( )。
A. 选择排序不是一个稳定的排序算法
B. 冒泡排序算法不是一种稳定的排序算法
C. `插入排序是一种稳定的排序算法
D. 如果排序前2个相等的数在序列中的前后位置顺序和排序后它们2个的前后位置顺序相同,则称为一种稳定的 排序算法
正确答案:B
11、数组{45,66,23,1,10,97,52,88,5,33}进行从小到大冒泡排序过程中,第一遍冒泡过后的序列是( )。
A. {45,23,1,10,66,52,88,5,33,97}
B. {45,66,1,23,10,97,52,88,5,33}
C. {45,66,23,1,10,52,88,5,33,97}
D. {45,66,23,1,10,97,52,88,33,5}
正确答案:A
12、下面的排序算法程序中,横线处应该填入的是( )。
int a[8] = {2, 3, 4, 5, 6, 2, 3, 1};
for (int i = 1; i < 8; i++){
int key = a[i];
int j = i - 1;
while (a[j] > key && j >= 0){
____
j -= 1;
}
a[j + 1] = key;
}
A. a[j]=a[j-1];
B. a[j]=a[j+1];
C. a[j+1]=a[j-1];
D. a[j+1]=a[j];
正确答案:D
13、下面的程序中,如果输入 10 0 ,会输出( )。
#include <iostream>
using namespace std;
double Division(int a, int b){
if (b == 0)
throw "Division by zero condition!";
else
return ((double) a / (double) b);
}
void func(){
int len, time;
cin >> len >> time;
cout << Division(len, time) << endl;
}
int main() {
try{
func();
}
catch (const char* errmsg){
cout << errmsg << endl;
}
catch (const int errmsg){
cout << errmsg << endl;
}
return 0;
}
A. Division by zero condition!
B. 0
C. 10
D. 100
正确答案:A
14、10条直线,最多可以把平面分为多少个区域( )。
A. 55
B. 56
C. 54
D. 58
正确答案:B
15、下面程序中,如果语句 cout<<p<<endl; 输出的是 0x6ffe00 ,则 cout<<++p<<endl; 输出的是()
int x[10][10][10] = {{0}};
int *p;
p = &x[0][0][0];
cout << p << endl;
cout << ++p << endl;
A. 0x6ffe0c
B. 0x6ffe09
C. 0x6ffe06
D. 0x6ffe04
正确答案:D
判断题(每题 2 分,共 20 分)
1、int& a和&a是一样的,都是取a的地址。
正确答案:错误
2、以下代码不能够正确执行。
#include <iostream>
using namespace std;
int main(){
int a = 20;
int& ra;
ra = &a;
cout << ra << endl;
}
正确答案:正确
3、引用是一个指针常量。
正确答案:正确
4、下面程序两个输出结果是一样的。
#include <iostream>
using namespace std;
int main(){
int a[2][3] = {0};
cout << a << endl;
cout << &a[0][0] << endl;
}
正确答案:正确
5、函数不可以调用自己。
正确答案:错误
6、函数参数传递过程中,如果传常量值、常量引用和常量指针都是不能被修改的,它们可以防止函数对实参的
值或地址进行修改。
正确答案:正确
7、下面代码输出的值等于0。
#include <iostream>
using namespace std;
int main(){
int *p = NULL;
cout << p << endl;
}
正确答案:正确
8、在下面这个程序里, a[i][j] 和一个普通的整型变量一样使用。
#include <iostream>
using namespace std;
int main(){
int a[10][10] = {0};
for (int i = 0; i < 10; i++){
for (int j = 0; j < 10; j++){
if (i == j){
a[i][j] = 1;
}
}
}
}
正确答案:正确
9、一个一维数组,至少含有一个自然数N,是一个合法的数列。可以在一维数组末尾加入一个自然数M,M不 能超过一维数组末尾元素的一半,形成一个新的合法的一维数组,如果N=6,那么可以有6个不同的合法数组。
正确答案:正确
10、插入排序算法中,平均时间复杂度是 O ( n 2 ) O(n^2) O(n2),最坏的情况逆序情况下,达到最大时间复杂度。
正确答案:正确
编程题 (每题 25 分,共 50 分)
黑白方块
【问题描述】
小杨有一个n行m列的网格图,其中每个格子要么是白色,要么是黑色。
对于网格图中的一个子矩形,小杨认为它是平衡的当且仅当其中黑色格子与白色格子数量相同。
小杨想知道最大的平衡子矩形包含了多少个格子。
【输入描述】
第一行包含两个正整数n, m,含义如题面所示。
之后n行,每行一个长度为m的01串,代表网格图第i行格子的颜色,如果为0,则对应格子为白色,否则为黑色。
【输出描述】
输出一个整数,代表最大的平衡子矩形包含格子的数量,如果不存在则输出0。
【样例输入 1】
4 5
00000
01111
00011
00011
【样例输出 1】
16
【样例解释】
对于样例1,假设 ( i, j) 代表第i行第j列,最大的平衡子矩形的四个顶点分别为 (1, 2),(1, 5),(4, 2),(4, 5)。
【数据范围】
对于全部数据,保证有1 <= n, m <= 10。
#include <iostream>
using namespace std;
char a[20][20];
int n, m, ans, cnt1, cnt0;
void input(char a[][20]){
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
cin >> a[i][j];
}
}
}
void output(char a[][20]){
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
cout << a[i][j] << ' ';
}
cout << endl;
}
cout << endl;
}
bool cmp(int qix, int qiy, int zhongx, int zhongy){
cnt1 = cnt0 = 0;
// 对比的时候要判断的是起点的x坐标到终点的x坐标
// 内层是起点的y坐标到终点的y坐标
for (int i = qix; i <= zhongx; i++){
for (int j = qiy; j <= zhongy; j++){
if (a[i][j] == '0')
cnt0++;
if (a[i][j] == '1')
cnt1++;
}
}
// printf("i = %d, j = %d, cnt1 = %d, cnt0 = %d\n", i, j, cnt1, cnt0);
return cnt1 == cnt0;
}
int main(){
cin >> n >> m;
input(a);
// 循环遍历起点的x,y坐标
for (int qix = 1; qix <= n; qix++){
for (int qiy = 1; qiy <= m; qiy++){
// 循环遍历终点的x,y坐标
for (int zhongx = qix; zhongx <= n; zhongx++){
for (int zhongy = qiy; zhongy <= m; zhongy++){
if (cmp(qix, qiy, zhongx, zhongy)){
// 如果比对成功
ans = max(ans, cnt0 * 2);
}
}
}
}
}
//output(a);
cout << ans << endl;
return 0;
}
宝箱
【问题描述】
小杨发现了n个宝箱,其中第i个宝箱的价值是
a
i
a_i
ai。
小杨可以选择一些宝箱放入背包并带走,但是小杨的背包比较特殊,假设小杨选择的宝箱中最大价值为x,最小价值为y,小杨需要保证x - y <= k,否则小杨的背包会损坏。
小杨想知道背包不损坏的情况下,自己能够带走宝箱的总价值最大是多少。
【输入描述】
第一行包含两个正整数n, k ,含义如题面所示。
第二行包含n个正整数
a
1
,
a
2
,
.
.
.
,
a
n
a_1, a_2, ..., a_n
a1,a2,...,an ,代表宝箱的价值。
【输出描述】
输出一个整数,代表带走宝箱的最大总价值。
【样例输入 1】
5 1
1 2 3 1 2
【样例输出 1】
7
【样例解释】
在背包不损坏的情况下,小杨可以拿走两个价值为2的宝箱和一个价值为3的宝箱。
【数据范围】
对于全部数据,保证有
1
<
=
n
<
=
1000
,
0
<
=
k
<
=
1000
,
1
<
=
a
i
<
=
1000
1 <= n <= 1000, 0 <= k <= 1000, 1 <= a_i <= 1000
1<=n<=1000,0<=k<=1000,1<=ai<=1000。
#include <iostream>
/*
n个宝箱,第i个宝箱的价值是ai
小杨"选择的宝箱"中最大值为x, 最小值为y
*/
const int maxn = 1e5;
using namespace std;
int n, k, a[maxn], ans, nmax, nmin;
void Sort(){
// 冒泡排序, 降序
for (int i = 1; i < n; i++){ // 比较n - 1次
for (int j = 1; j < n - i + 1; j++){
if (a[j] < a[j + 1]){
swap(a[j], a[j + 1]);
}
}
}
}
int main(){
cin >> n >> k;
for (int i = 1; i <= n; i++){
cin >> a[i];
}
Sort();
// 假设当前拿到的是最大值, 然后枚举每一个宝箱, 看能拿到的价值有多少
for (int i = 1; i <= n; i++){
int sumn = a[i];
for (int j = i + 1; j <= n; j++){
if (a[i] - a[j] <= k){
sumn += a[j];
}
}
ans = max(ans, sumn);
}
cout << ans << endl;
return 0;
}