2019 CSP-S / NOIP提高组初赛试题解析 (下)
二、阅读程序
1.
程序分析: 本段程序的目的是找到每个a[i]之后第一个大于a[i]的位置(下标ans+1)。代码简单,即使看不懂也可以代入几个数字去试验,毕竟选择题。
1) 第16行输出ans时,ans的值一定大于i。( )
解析:错。只要14行while循环不执行,则ans=i,如n=1,则ans等于i。
2) 程序输出的ans小于等于n。( )
解析:对。ans初始值为i小于n,且小于n是其自增的一个条件,显然不会超过。
3) 若将第12行的“<”改为“!=”,程序输出的结果不会改变。( )
解析: 对。改成!=只是增加了一些没意义的比较,对结果没有影响。
4) 当程序执行到第16行时,若ans-i>2,则a[i+1]≦a[i]。( )
解析:对。因为ans+1是第一个大于a[i]的位置,所以从a[i+1]至a[ans]都是小于等于a[i]的。
5) 若输入的a数组是一个严格单调递增的数列,此程序的时间复杂度是( )。A.O(logn) B.O(n^2)C.O(nlog n) D. O(n)
解析:D。严格单调递增则14行必定不执行,while循环每次只执行一次,时间复杂度为n。
6) 最坏情况下,此程序的时间复杂度是( )。A. O(n^2) B. O(logn)C. O(n) D. O(nlog n)
解析:A。最坏的情况为严格单调递减,14行if判断每次都执行,while循环每次都查找到n,时间复杂度为n+(n-1)+……+2+1=n*(n+1)/2,即O(n^2)。
程序分析: 本题就是一个并查集操作,getRoot函数是查询根节点,循环中对集合进行合并。
1) 输入的a和b值应在[0,n-1]的范围内。( )
解析:对。输入的a、b是集合的下标,自然应该在[0,n-1]之间。
2) 第16行改成“fa[i]=0;”, 不影响程序运行结果。( )
解析:错。未合并前初始根节点是其本身,为0显然不符合题意。
3) 若输入的a和b值均在[0, n-1]的范围内,则对于任意0≤i<n,都有0≤fa[i]<n。(
解析: 对。fa[i]是根节点,不管在怎么合并,根节点必然也是在[0,n-1]之间。
4) 若输入的a和b值均在[0,n-1]的范围内,则对于任意0≤i<n,都有1≤cnt[i] ≤n。
解析:错。cnt[i]是合并之后集合的元素个数,严谨的并查集操作cnt[i]是不会超过n的,但是本题没有判断是否重复合并。所以如果先输入(1,2),(3,4),之后一直不断输入(2,4),最后cnt[4]会超过n。
程序分析: 本题主要需了解两个数组的含义,pre[i]表示s[0..i]至多可以从前往后匹配到t串的哪一个字符,此时t[0..pre[i]-1]是s[0..i]的子序列。sub[i]用于记录s[i..slen-1]至多从后到前匹配到t的哪一个字符,此时t[suf[i]+1..tlen-1]是s[i..slen-1]的子序列。本题是求s中连续删除至多几个字母后,t仍然是s的子序列。
1) 程序输出时,suf数组满足:对任意0≤i<slen,suf[i] ≤suf[i+1]。( )
解析:对。从15至19行可以看出,sub数组的值是从尾部往前减小或不变,所以suf[i] ≤suf[i+1]。
NOIP信息学视频地址
视频地址
链接:https://pan.baidu.com/s/1tHo1DFMaDuMZAemNH60dmw
提取码:7jgr