2019[CSP/NOIP]初赛普及组解析(下)

二、阅读程序

1.

 

 程序分析: 对于输入字符串中的第i位,如果i是n(字符串长度)的约数,并且第i个字符比'a'(97)要大,就-'a'+'A',即小写转大写操作

1) 输入的字符串只能由小写字母或大写字母组成。( )

解析:错。可以输入数字或符号。

2) 若将第8行的“i=1”改为“i=0”,程序运行时会发生错误。( )

解析:对。i为0时取模会报错

3) 若将第8行的“i<=n”改为“i*i<=n”,程序运行结果不变。( )

解析: 错。约数是可能超过sqrt(n)的,范围缩小了

4) 若输入的字符串全部由大写字母组成,那么输出的字符串就跟输入的字符串一样。( )

解析:对。大写的ASCII值小于小写,字符不进行变换。

5) 若输入的字符串长度为18,那么输入的字符串跟输出的字符串相比至多有( )个字符不同。

A.18 B.6 C.10 D.1解析:B。18的约数有6个(1、2、3、6、9、18)。

6) 若输入的字符串长度为( ),那么输入的字符串跟输出的字符申相比,至多有36个字符不同。

A.36 B.100000 C.1 D.128

解析:B。10000 = 2^5 * 5^5,一共有(5 + 1) * (5 + 1) = 36个约数,用枚举法也能轻易排除其他三个选项。

2.

 

 

 

 程序分析: 有a、b两组元素,两组元素之间可以两两对应。初始时所有元素都和另一组的0对应。每次考察a组的第x个元素和b组的第y个元素,如果这两个元素之前的配对交叉了,则把它们之前的配对元素重置为0,并将这两个元素配对。

1) 当m>0时,输出的值一定小于2n。( )

解析:对。m>0至少一个配对,多以结果必小于2n。

2) 执行完第27行的“++ans”时,ans一定是偶数。( )

解析:错。本题相当于两个数组间由若干条线有对照关系,最终的ans必定为偶数,但是单边不一定。

3) a[i]和b[i]不可能同时大于0。( )

解析: 错。令m=1,输入x=1,y=1时, a[i]和b[i]同时为1。

4) 程序执行到13行时,x总是小于y,那么第15行不会被执行。( )

解析:错。若果x之前已经配对过,则会重新更新,反例:(1,2)、(1,3)。

5) 若m个x两两不同,且m个y两两不同,则输出的值为( )。

A. 2n-2m B.2n+2 C.2n-2 D.2n

解析:A。m次循环中会有2m个位置的值会变化,ans=2n-2m。

6) 若m个x两两不同,且m个y都相等,则输出的值为( )。        A.2n-2        B.2n         C.2m           D.2n-2m

解析:A。x和y配对时每次都会清理掉之前的配对,最终只会产生一组配对,所以和0配对的元素数量为2n - 2

3.

 

 

 

 程序分析: 将数组b根据数组a值构造成一棵二叉树,每次在序列中选择a值最小且最靠前的元素作为根,根之前的序列构建左子树,根之后的序列构建右子树。最后求每个节点值b[i]乘深度deep的和。

1) 如果a数组有重复的数字,则程序运行时会发生错误。( )

解析:错。每次是找第一次出现的最小值,重复不影响。

2) 如果b数组全为0,则输出为0。( )

解析:对。最后求每个节点值b[i]乘深度deep的和。

3) 当n=100时,最坏情况下,与12行的比较运算执行的次数最接近的是( )A.5000 B.6000 C.6 D.100

解析: A。最坏情况为每次的min都在最左或最右,一次只能构建单侧子树,每层只少一个点。则总比较次数为100+99+98+……+1 = 5050。

4) 当n=100时,最好情况下,与12行的比较运算执行的次数最接近的是 ( )A.100 B.6 C.5000 D.600

解析:D。最好情况是每次min都在序列中间,刚好平分两个子树,则深度大致为log(100)≈6,每层大概执行100次。

5) 当n=10时,若b数组满足,对任意0≤i<n,都有b[i]=i+1,那么输出最大为(

A.386 B.383 C.384 D.385

解析:D。最大值为权值最大的深度最深,结果为10*10+9*9+8*8+……2*2+1*1=385。

6) 当n=100时,若b数组满足,对任意0≤i<n,都有b[i]=1,那么输出最小为( )。
A.582 B.580 C.579 D.581
解析:B。即构造一个100节点的二叉树,想要值最小则尽可能弄成完全二叉树。
 
三、完善程序
1.

 

 

 

 
 
① 处应填( )
A.n%2 B.0 C.t D.1
解析:C。res仅有这处赋值,从题意和递归调用时t的赋值可知为t。
② 处应填( )
A.x-step,y-step B.x,y-stepC.x-step,y D.x,y
解析:D。四次递归调用代表一个数扩充为4个,x、y是其坐标,②处为左上,坐标不变。
③ 处应填( )A. x-step,y-step B. x+step,y+stepC. x-step,y D. x,y-step
解析:B。四次递归调用代表一个数扩充为4个,x、y是其坐标,③处为右下,x、y均增加。
④ 处应填( )A.n-1,n%2 B.n,0 C.n,n%2 D.n-1,0
解析:B。第一次调用recursive函数,n是矩阵规模,初始为n,t是取反次数,所以t初始为0。
⑤ 处应填( )A.i<<(n+1) B.1<<n    C.n+1      D.1<<(n-1)
解析:B。size是输出矩阵的边长,2^n,位运算是1<<n。
 
2

 

 

 

 ①处应填( )      A. ++cnt[i]         B. ++cnt[b[i]]           C. ++cnt[a[i]*maxs+b[i]]            D. ++cnt[a[i]]

解析:B。先对第二关键字进行计数。

②处应填 ( )A. ord[--cnt[a[i]]]=iB, ord[--cnt[b[i]]]=a[i]C. ord[--cnt[a[i]]]=b[i]D. ord[--cnt[b[i]]]=i
解析:D。cnt[b[i]]表示按第二关键字排序,第i个数排第几位。Ord[i]表示第i小的数在原序列的位置
 
③处应填( )A. ++cnt[b[i]]B. ++cnt[a[i]*maxs+ b[i]]C, ++cnt[a[il]D. ++cnt[i]
解析:C。再对第一关键字进行计数。
 
④处应填( )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。再对第一关键字进行计数。res[i]表示第一关键字第i小的数在原序列的位置。
 
⑤处应填( )A. a[i],b[i]B. a[res[i]], b[res[i]]C. a[ord[res[i]]], b[ord[res[i]]]D. a[res[ord[i]]], b[res[ord[i]]]
解析:B。res[i]记录第i个数的在原序列的位置。且a、b数组内容必然成对输出,下标必须一致,也可以简单猜测选B。
 

NOIP信息学视频地址

视频地址

链接:https://pan.baidu.com/s/1tHo1DFMaDuMZAemNH60dmw 
提取码:7jgr

 
 
posted @ 2020-10-14 10:15  tianli3151  阅读(1187)  评论(0编辑  收藏  举报