第二屆全國大學生算法設計與編程挑戰賽(春季賽)正式賽題解&比賽回顧


前言

很幸運地拿到了 rank 1!感謝主辦方老板(

這次 rank 1 主要還是運氣不錯,第二次打 ACM 賽制就碰上了配合這么默契的隊友,然后關鍵題都做得比較順利。

比賽回顧

咕咕咕

題解

題解會盡量照顧到所有水平的選手,會很通俗易懂 =w=

如果我沒更新記得私信/QQ催我!

Overall

題目編號 A B C D E F G H I J K L
思維難度 0 3 1 0 5 2 2 0 6 4 ? 0
實現難度 0 1 1 1 3 2 2 1 7 3 ? 0

所有難度均從 \(0\)\(10\) 打分。

Problem A 智慧果

題面 已知序列 $a$:
  • \(a_1=1,a_2=2,a_3=3\)
  • \(a_i=a_{i-1}a_{i-2}a_{i-3}+a_{i-1}+a_{i-2}+a_{i-3}\)

\(a_{1000}\)\(100000\) 取模的值。

題解 暴力計算每一項對 $100000$ 取模的值即可。

時間復雜度 \(O(n)\),其中 \(n\) 為項數。

代碼

Problem B Xanadu

題面 給定一個 $n\times n$ 的 $01$ 矩陣,和 $n$ 個點的圖。你可以花費 $1$ 的代價將矩陣中的一個 $1$ 變成 $0$。

操作完成后,記第 \(i\) 行從左到右第一個為 \(1\) 的位置為 \(j\),則在圖上從 \(i\)\(j\) 之間連一條有向邊。

問至少要花費多少代價,才能讓圖上存在一條從 \(1\)\(n\) 的路徑,如果無法達成輸出 \(-1\)

\(n\leq 300\)

題解 不難發現最后得到的一定是一棵基環樹,因此如果有路徑,必然存在一條無環的路徑,即每個點僅經過一次。

我們對於矩陣建圖。假設第 \(i\) 行的第 \(j\) 個位置是該行第 \(k\)\(1\),我們就從 \(i\)\(j\) 建一條費用為 \(k-1\) 的邊。

不難發現,最后得到的每條從 \(1\)\(n\) 的路徑的邊權總和就是這個方案要花費的代價,因此直接在原圖上跑最短路即可。

時間復雜度 \(O(n^2)\)\(O(n^2\log n)\)

代碼

Problem C 這是一道大難題

題面 給定一張圖,求其必須包含給定一條邊的最小生成樹。

\(n\leq 10^5,m\leq 2\times10^5\)

題解 直接先加入這條邊,然后跑 Kruskal 算法即可。

正確性顯然。

時間復雜度為 \(O(m\log m+n\alpha(n))\)

代碼

Problem D zeal

題面 給定長度為 $n$ 的序列 $a$,$m$ 次求 $[l,r]$ 中出現 $k$ 次的元素數量。

\(n,m,a_i\leq 4\times 10^4\)

題解 直接上莫隊算法即可。

時間復雜度 \(O(n\sqrt m)\)

代碼

Problem E Alice 大戰 Bob

題面 給定一個長度為 $n$ 的序列,有 $m$ 次詢問。

每次詢問給定 \(l,r\),Alice 和 Bob 依次操作,每次操作可以將 \(l\)\(1\) 或者 \(r\)\(1\)。操作后 \([l,r]\) 內的數若單調不升或單調不降,操作者獲勝。

\(n,m\leq 10^6\)

題解 做法和 AGC002E 十分類似。

先把所有已經單調不升或單調不降的區域求出。

然后把一步能走到這些區域的位置求出。

於是問題變成了 AGC002E,可以自行查閱該題題解。

時間復雜度為 \(O(n+m)\)\(O(n+m\log n)\)

代碼

Problem F 這是一道大水題

題面 給定 $n$ 個操作,每個操作為將 $[l,r]$ 的數加 $k$。

\(m\) 次詢問只執行 \(t\notin[l,r]\) 的操作后 \([1,n]\) 的和。

\(n,m\leq 10^6\)

題解 注意到執行的操作對答案的貢獻都是 $(r-l+1)\times k$。

於是對所有操作記錄其 \(l,r\) 和貢獻,統計答案時統計所有 \(r\) 小於 \(t\)\(l\) 大於 \(t\) 的操作貢獻和即可,這個可以通過線段樹簡單實現。

時間復雜度 \(O((n+m)\log n)\)

代碼

Problem G List it all

題面 給定 $n$ 個 $1\sim 9$ 的數字,問能組成的所有不同數的和,對 $10^9+7$ 取模。

\(n\leq 2\times 10^6\)

題解 所有數的和等於數的個數加上所有數的平均數。

數的個數和可以通過組合數公式簡單計算,這里不再贅述。

對於平均數,不難發現每一位的數的平均值都等於給定的所有數的平均值,設每位平均值為 \(k\),總平均值即 \(11\cdots1\times k\)

代碼

Problem H 智慧數

題面 定義一個數 $x$ 是好的,當且僅當存在一個正整數 $y|x$,使得 $x\neq y$ 且 $xy$ 為完全平方數。

求從小到大第 \(3000\) 個好數。

題解 對每個數暴力枚舉因數檢驗即可。

記答案為 \(n\),存在 \(O(n^2),O(n\sqrt n),O(n\log n)\) 的解法。

代碼

Problem I Imp

題面 給定一個長度為 $n$ 的 $01$ 串和 $m$。

你可以翻轉單個字符,或同時翻轉前 \(m\) 的倍數個字符,代價均為 \(1\)

問使得字符串前 \(n-m\) 個字符和后 \(n-m\) 個字符全部相等的最小代價。

\(n,m\leq 300\)

題解 比較有趣的一題。
  • Case 1

如果 \(2(n-m)\leq n\),即兩段字符不交的情況中,由於整體翻轉僅有一個操作,枚舉是否執行這個操作后,對於每對字符判斷是否需要翻轉即可。

時間復雜度 \(O(n)\)

  • Case 2

考慮進行轉化,記 \(f_i=[a_i=a_{i+m}]\),則對字符串的操作可以轉化為對 \(f_i\) 的操作,目標為讓 \(f_i\) 的。

注意到操作的特點,我們將 \(f_i\)\(m\) 個組成一行,共 \(\lceil\frac{n-m}{m}\rceil\) 行。

我們記行數為 \(N\),列數為 \(M\)

操作可以轉化成每行和每列的操作,即翻轉每行,翻轉每列最上面和最下面的一格,翻轉每列連續的兩格。

於是一個暴力產生了:枚舉每行是否翻轉后對整個矩陣求答案,時間復雜度為 \(O(2^M\text{poly}(n))\)

然后我們發現我們還可以再寫一個暴力:

假設我們已經把和前 \(i\) 行相關的所有操作做完了,第 \(i+1\) 行的狀態為 \(S\) 的最小操作數為 \(f_{i,S}\),我們可以通過 dp 來求得答案,時間復雜度為 \(O(2^N\text{poly}(n))\)

因此,我們可以根號分治這兩種情況,時間復雜度為 \(O(2^{\min(N,M)}\text{poly}(n))=O(2^{\sqrt n}\text{poly}(n))\),可以通過。

代碼

Problem J 這是一道送分題

原題洛谷 P2466。

Problem K Chanllaging Problem

題面 咕咕咕
題解 咕咕咕
代碼 咕咕咕

Problem L 這是一道壓軸題

題面 給定一個 $01$ 串,問刪除一個極長相同字符子串后能得到最長的極長相同字符子串。

\(|S|\leq 10^6\)

題解 顯然得到的子串就是原來就有的串或者原來只隔一個極長相同字符子串的極長相同字符子串。

找到極長相同字符子串后枚舉即可。

時間復雜度 \(O(|S|)\)

代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM