二、閱讀程序
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
