三、完善程序
34. ①处应填( )
A. n%2
B. 0
C. t
D. 1
解析:
背景知识:
位运算
任何信息在计算机中都是采用二进制表示的,数据在计算机中是以补码形式存储的,位运算就是直接对整数在内存中的二进制位进行运算。根据NOI大纲要求,入门级阶段需要掌握的位运算有与(&)、或(|)、非(~)、异或(^)、左移(<<)和右移(>>)。
位运算规则
与(&):两个位都为1时,结果才为1
或(|): 两个位都为0时,结果才为0
非(~): 0变1,1变0
异或(^):两个位相同为0,相异为1
左移(<<): 各二进位全部左移若干位,高位丢弃,低位补0
右移(>>):各二进位全部右移若干位,对无符号数,高位补0
有符号数,各编译器处理方法不一样,有的补符号位(算术右移),有的补0(逻辑右移)
数组
数组(Array)是一种复合数据类型,它由一系列相同类型的元素(Element)组成,数组中的元素通过下标(或称为索引,Index)来访问。
二维数组
二维数组本质上是以数组作为数组元素的数组,即“数组的数组”。
二维数组定义的格式为:
类型 数组名[行数][列数];
行数表示第一维下标的长度
列数表示第二维下标的长度
函数定义
返回类型 函数名([参数列表])
{
函数体//执行语句
}
包括以下几个部分:
函数名:为函数所起的名字,必须是一个有效的C++标识符,给变量命名的规则同样也适用于给函数命名,但要注意,不可以使用C++的保留字作为函数名。
函数参数:包括形式参数和实际参数。
形式参数是用逗号分隔的变量说明列表,这些变量称为函数的形式参数。形式参数用于接收从函数调用程序传给这个函数的数据。
实际参数是用逗号分隔的表达式列表,其中每一个表达式称为实际参数。在函数调用时,需要将实际参数的值传送给对应位置的形式参数,因此它们两个参数的个数必须相同,而且数据类型也必须匹配。
函数体:函数体是使用花括号{ }限定的语句序列,分为说明部分和语句部分,用于描述这个函数所要执行的操作。说明部分用来对函数中使用的变量和函数作说明。语句部分由基本语句组成,函数的功能由函数体内的各个语句的执行来实现。
函数调用
一个函数被定义后,程序中的其他函数就可以使用这个函数,这个使用的过程就称为函数调用。
函数名(实参列表);
递归函数
直接调用自己或通过一系列的调用语句间接地调用自己的函数,称为递归函数。递归通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,一个问题想要用递归的函数(方法)来解决,必须要符合两个条件:
1.可以把这个问题转化成一个新问题,而新问题的解法和原问题的解法完全相同,但问题的规模变小了
2.必须要有一个明确的递归结束条件(边界)
知识点分类:
C++程序设计-函数与递归-递归函数的概念、定义与调用
C++程序设计-基本运算-位运算
答案解析:
首先分析下题目所给的代码:
通过代码分析可知,本题程序实现的功能是:利用递归函数,将初始矩阵{0}变换n次(n<10)。变换的方法是调用recursive函数递归求出奇幻矩阵的四个角,并输出变换好的矩阵。
①处所在的位置是程序递归结束的条件,前边的if条件是n的值为0,此时二维数组res[x][y]的值应该为t,表示矩阵不需要进行变换。
所以本题的正确答案应该选择C。
35. ② 处应填( )
A.x-step,y-step
B.x,y-step
C.x-step,y
D.x,y
程序14-17行的作用是使用递归函数求矩阵的四个角:
左上角:(x,y)
右上角:(x,y+step)
左下角:(x+step,y)
右下角:(x+step,y+step)
②处对应的递归函数是求矩阵的左上角,即为(x,y)
所以本题的正确答案应该选择D。
36.③ 处应填( )
A. x-step,y-step
B. x+step,y+step
C. x-step,y
D. x,y-step
解析:
程序14-17行的作用是使用递归函数求矩阵的四个角:
左上角:(x,y)
右上角:(x,y+step)
左下角:(x+step,y)
右下角:(x+step,y+step)
③处对应的递归函数是求矩阵的右下角,即为(x+step,y+step)
所以本题的正确答案应该选择B。
37.④处应填( )
A. n-1,n%2
B. n,0
C. n,n%2
D. n-1,0
解析:
④处所在的22行程序是调用递归函数recursive,函数有四个参数,此处需要填入后两个参数;
第一个参数应该填入n,表示初始矩阵需要变换的次数;
根据题目的描述可知,矩阵初始的状态应为[0],所以第二个参数应该填入 0;
所以本题的正确答案应该选择B。
38. ⑤处应填()
A. 1<<(n+1)
B. 1<<n
C. n+1
D. 1<<(n-1)
解析:
⑤处所在程序是定义矩阵的长度和宽度,即最终奇幻矩阵的大小。
最初的矩阵是{0}:
变换1次,奇幻矩阵的长度和宽度均为2;
变换2次,奇幻矩阵的长度和宽度均为4;
……
变换n-1次,奇幻矩阵的长度和宽度均为2n-1;
根据上述规律可知:变换n次,奇幻矩阵的长度和宽度对应的变量size的值应为2n
而根据位运算的规则可知:2n=1<<n
所以本题的正确答案应该选择B。
39. ①处应填( )
A. ++cnt [i]
B. ++cnt[b[i]]
C. ++cnt[a[i] * maxs + b[i]]
D. ++cnt[a[i]]
解析:
背景知识:
数组
数组(Array)是一种复合数据类型,它由一系列相同类型的元素(Element)组成,数组中的元素通过下标(或称为索引,Index)来访问。
二维数组
二维数组本质上是以数组作为数组元素的数组,即“数组的数组”。
二维数组定义的格式为:
类型 数组名[行数][列数];
行数表示第一维下标的长度
列数表示第二维下标的长度自增自减运算符在C++等高级程序设计语言中,自增或自减运算符的作用是在运算结束前(前置自增自减运算符)或运算结束后(后置自增自减运算符)将变量的值加(或减)1。例如:++i 先使i的值自增1,再使用i的值– – i 先使i的值自减1,再使用i的值i++ 使用i的值之后,使i的值自增1i- – 使用i的值之后,使i的值自减1
函数定义
返回类型 函数名([参数列表])
{
函数体//执行语句
}
包括以下几个部分:
函数名:为函数所起的名字,必须是一个有效的C++标识符,给变量命名的规则同样也适用于给函数命名,但要注意,不可以使用C++的保留字作为函数名。
函数参数:包括形式参数和实际参数。
形式参数是用逗号分隔的变量说明列表,这些变量称为函数的形式参数。形式参数用于接收从函数调用程序传给这个函数的数据。
实际参数是用逗号分隔的表达式列表,其中每一个表达式称为实际参数。在函数调用时,需要将实际参数的值传送给对应位置的形式参数,因此它们两个参数的个数必须相同,而且数据类型也必须匹配。
函数体:函数体是使用花括号{ }限定的语句序列,分为说明部分和语句部分,用于描述这个函数所要执行的操作。说明部分用来对函数中使用的变量和函数作说明。语句部分由基本语句组成,函数的功能由函数体内的各个语句的执行来实现。
它是直接操作内存空间,mem即“内存”(memory)的意思。
函数的原型为:
void *memset(void *s, int c, unsigned long n);
void *memset(void *s, int ch, size_t n);
sizeof
sizeof 是一个关键字,是一个编译时运算符,用于判断变量或数据类型的字节大小。
sizeof 运算符可用于获取类、结构、共用体和其他用户自定义数据类型的大小。
使用 sizeof 的语法如下:
其中,data type 是要计算大小的数据类型,包括类、结构、共用体和其他用户自定义数据类型。
知识点分类:
算法-排序算法
答案解析:
首先分析下题目所给的代码:
通过代码分析可知,本题程序实现的功能是:对若干个整数对(a[maxn],b[maxn])进行计数排序。先根据第二关键字b进行排序,再根据第一关键字a进行排序,最后输出排序后的整数对。
根据上述分析可知:①处是要根据第二关键字数组b进行排序,并对关键字的数量进行统计。因此应该让数组b[i]作为关键字,同时对cnt数组进行自增操作,即为++cnt[b[i]]。
所以本题的正确答案应该选择B。
40. ②处应填( )
A. ord[–cnt[a[i]]] = i
B. ord[–cnt[b[i]]] = a[i]
C. ord[–cnt[a[i]]] = b[i]
D. ord[–cnt[b[i]]] = i
解析:
根据上述分析可知: ②处是要根据第二关键字数组b进行排序,并记录排序的结果。而ord数组就是用来存放排序后的结果。
对于任意的b[i],cnt[b[i]]的值至少应该为1,而数组的下标是从0开始,所以要使用前置自减运算符–,将cnt[b[i]]先自减后再进行赋值,即为:ord[–cnt[b[i]]] = i
所以本题的正确答案应该选择D。
41. ③处应填( )
A. ++cnt[b[i]]
B. ++cnt[a[i] * maxs + b[i]]
C. ++cnt[a[i]]
D. ++cnt [i]
解析:
根据上述分析可知:③处是要根据第一关键字数组a进行排序,并对关键字的数量进行统计。因此应该让数组a[i]作为关键字,同时对cnt数组进行自增操作,即为++cnt[a[i]]。
所以本题的正确答案应该选择C。
42. ④处应填( )
A. res[–cnt[a[ord[i]]]] = ord[i]
B. res[–cnt[b[ord[i]]]] = ord[i]
C. res[–cnt[b[i]]] = ord[i]
D. res[–cnt[a[i]]] = ord[i]
解析:
根据上述分析可知:④处是要根据第一关键字数组a进行排序,并记录排序结果,所以可以排除B和C选项。
而题目提示中明确指出,数组ord[]存储第二关键字排序的结果。因为在此之前程序已经对第二关键字b进行了排序,所以此时元素i的下标已经变为了ord[i],可以排除D选项。
数组res[]存储的是双关键字排序的结果;和②处原理相同,cnt[]数组需要先自减后再进行赋值,所以④处应填res[–cnt[a[ord[i]]]] = ord[i] 。
本题的正确答案应该选择A。
43. ⑤处应填( )
A. a[i], b[i]
B. a[res[i]], b[res[i]]
C. a[ord[res[i]]]j b[ord[res[i]]]
D. a[res[ord[i]]]j b[res[ord[i]]]
解析:
题目提示中明确指出,数组res[]存储的是双关键字排序的结果。程序已经按照第二关键字数组b、第一关键字数组a进行了排序,此时元素i的下标已经变为了res[i]。所以最终输出数组a和数组b的元素时,两个数组的下标应该为res[i],即a[res[i]], b[res[i]] 。
本题的正确答案应该选择B。