競程
建資 張庭瑋
什麼是競程
用演算法解決作者提出的問題,並以這個能力當作比賽的項目
大部分的人都是用 C++ 的
先講我有經歷過的最好玩的
選訓
- 一個為期 14 天的活動
- 總共會有兩個階段 (叫做 1!,2!)
- 念法是 數字+階
- 1! 會是 ~30 人選 12 人進入 2!
- 2! 會從 12 人選 4 人當上國手
也就是去 IOI 啦
選訓
IOI
先聲明:我沒去過
- 全稱資訊奧林匹亞,是高中以下競程圈的最高殿堂
- 有得牌的話教育部會給獎金跟保送資格
金額:金/銀/銅 分別是 20/10/5 (萬) - 每年會在不同的國家舉辦
- 每個國家一年只有四個人可以去
- 今年在匈牙利
選訓都在幹嘛
- 大概是早九到晚五
- 大部分的時段都會有安排教授上課
但是可以不用聽- 晚上會有拼圖活動,或是體育課
- 也會有各種前國手回來演講
- 國家請你住飯店
- 週六會有正式考試,但是叫做模考
數奧:每天一場考試
去選訓能幹嘛
- 有進 1! 基本上就保底清交特選
- 有 2! 的話可以推薦台大,幾乎都會收
不像隔壁數奧那樣沒有推薦可以用 - 要是國手就能保送
結論
就是國家請你度假兩個禮拜
順便讓你有大學念啦
等等怎麼那麼快就跳結論了
所以好玩的點在哪
拜見各路大神的機會
想像一下,你有一個很景仰的人物
然後你突然有一天能跟他面對面講話了
你會驚訝地發現,原來常人跟這些人也沒什麼不一樣
他們跟你一樣會上廁所
輔導員
- 跟在你們旁邊的一群人
- 大部分都是師大資工系的學生
- 陪著你們吃喝玩樂的領隊
- 很有趣,很好相處
- 每天晚上會叫你去點名順便拿消夜
- 草莓奶茶
晚上的活動
- 基本上每天晚上會安排不是體育課就是拼圖時間
- 體育課有各種可能,遇過重訓也遇過跑 1600
- 拼圖因為太好玩了所以有人會在自習時繼續拼
- 整體上是為了放鬆眼睛跟身體的活動啦
- 前年玩遊戲輸的懲罰都在伏地挺身
去年因為某堂體育課所以我們多了深蹲膜拜這個懲罰
真 晚上的活動
- 晚上回飯店之後是自由時間
- 沒有門禁 誰管你
- 飯店的對面是安利美特,可以哀求輔導員帶你去
選訓很多人都蠻油的,一去就是二十幾個人 - 其他活動像是撲克牌、實體日麻、狼人殺等等
- 平常大概會玩到一兩點才睡覺
考試前一天會早睡
怪話
有教授會畫加菲貓
可以每次他上課的時候求他畫
目前已經第五年了
附上去年的照片跟某個學測完要女裝的學長
要怎麼取得資格
兩個管道:全國賽或是初選
都需要一定的競程實力
所以競程可以幹嘛?上大學(O
初選
- 三月舉辦
- 大概會選出 20 個人
- 每個年級會各保障四個,女生保障六個
國三以下跟高一一起保障 - 算是競程圈下一個大活動(?
學科能力競賽
辦在九月到十二月
所以高一的沒有聽過很正常
流程:
校內賽
地區複賽
全國賽
校隊選拔
這個就因各校而定
建中的話會是去年比過全國賽的人出題
其他校我不清楚
北市賽
選出 ~ 10 個人去比全國賽
題目品質是每年都可以拿出來嘴砲的等級
每年都有題目出爛
關於題目出爛
大前提:競程的題目數量/時間跟段考完全不成比例
介紹兩種不同的比賽制度
OI
- 沒有 penalty
- 有部份分
- 題數少 (3~5)
ICPC
- 有 penalty
- 沒有部份分
- 題數多 (10~15)
比較
相同處:兩個都可以提交答案很多次
並且及時知道正確與否
penalty
- 中文稱作罰時
- 與 "你通過的時間" 及 "你上傳的次數" 有關
- 舉個例子:
同一題花三分鐘寫完跟花三十分鐘寫完獲得的分數會不一樣
部份分
有點像是小題制,每題在你做出了一些中間結果就會給你一部份的分數
回到正題
北市賽是 OI 制
總共三小時五(六)題,粗略估計就是平均一題有 36 分鐘可以寫
而一題題目出爛的情況就會導致你浪費了那麼多時間
這個是很多人都不能忍受的
可不是像段考那樣送分就算了
補充
剛剛講的選訓模考也是 OI 制,五小時四題
基本上高中的大部分比賽都是這種制度
因為這是資奧官方採用的制度
然後選訓模考也是整天題目出包
希望今年不要 QQ
全國賽
- 特殊一點的 OI 制,五小時九題
- 各種難度的都有
- 台灣比的到的正式比賽中品質最好的
- 前兩等 (10 名) 能夠保送 1!
- 三個等第的獎金分別是 15000/10000/7500
有趣的地方
- 前一天的晚上有合菜的晚宴
- 是另一個能夠把台灣南北的人聚在一起的機會
- 晚上也是住飯店
除了上面兩條路之外...
APCS
- 同樣是演算法相關,但是難度大大降低
- 分成觀念題與實作題兩個考試
- 台大 APCS 組
- 清交特選
- 名額比較多,放在學習歷程也能加分
如何練習
1. 先學會 C++ 語法 這很重要
因為大部分找的到的資源都是使用 C++
其他語言的話初期會很辛苦
到了後期甚至會面臨一些語言本身上的問題
2. 去一些 OJ 開始刷題目
確保能掌握語法
大概要到什麼程度呢?
雖然因人而異,而且越學越多後會越來越熟悉
但我覺得需要滿足基本的東西不需要思考就寫得出來
不過我當初學的時候也沒有這麼厲害就是了啦
這個階段的 OJ 推薦:
Zerojudge
不用刷太多
感覺不會三不五時需要查語法的話就可以到下一個階段了
另外,這時候可以開始打各種比賽了
舉凡 Codeforces, Atcoder 等等
各種比賽
- 上面不定期舉辦各種比賽,比賽制度大概是類 ICPC 制
- 有很多 Blog 可以讀
- Gym 裡面也有其他類型的比賽可以用
- 是最古老也最多人使用的比賽網站,現在有十萬多人
Codeforces 的比賽
- 從難到易分別叫做 div.1 ~ div.4
- div.3, div.4 是簡單的,推薦初學的打
- div.2 會有一些有趣的題目,是適合所有人的
- div.1 建議有一定程度再來打
- 日本的網站,特點是簡約
- 週六週日會固定舉行比賽
- 比賽有三種,叫做 ABC/ARC/AGC
其中 ABC 共八題,前幾題很簡單但是破台很難
ARC 共六題,通常都是很多思考的
AGC 是難版的 ARC - 初學的話 ABC 是不錯的選擇
NPSC
- 台大辦的實體的比賽,約在十一月
- 三人一隊但是只能一機
- 分初賽跟決賽
- 獎品優渥,第一名是每人一台電腦
- 氣球氣球氣球
YTP
- 暑假的時候企業辦的比賽
- 三人一隊
- 在外面辦的比賽中題目品質算好
- 有很多吃的
- 有獎金,也有很多隊會獲得跟著教授做專題的機會
HP codewar
- 我沒打過XD
- 也是有很多獎金
- 題目品質普普(?
Meta Hacker cup
- 對,就是 FB 辦的比賽
- 線上賽
- 因為是全球性的,會在各種時段都有可能也曾經有過台灣半夜 1:00~4:00 的比賽
- 一年一度,有三個階段,前 2000 名有 T-shirt,前 200 名的 T-shirt 上面會有特殊的字
- 另一個很類似的叫做 Google code jam
貪心
什麼是貪心
人的本性就是每次都拿對自己最好的
什麼是對自己最好的?
最大值/最小值 ...
例題:稻草人
最左邊的稻田一定要被保護到
保護方式:選擇最左邊的沒有被保護到的稻田,然後在他右邊那格放一個稻草人
翻譯:有 n 個任務,每個任務都有持續時間以及死線,你同時只能進行一個任務
在時間 k 完成死線為 d 的任務會有 d-k 的報酬 (可以是負的)
必須完成所有任務,求最大報酬
每個任務晚一分鐘造成的損失是相同的
假設先完成了第一個任務,這個任務會對剩下的任務造成什麼影響
答案:先完成需要的時間比較短的任務
線段香蕉
有 n 根香蕉,田地是一個 [0,inf] 的數線,每根香蕉長在 [l,r] 的田地內,你想要留下一些香蕉繼續種,讓任意兩根香蕉都不佔據同一個位置,請問最多能留下多少根香蕉
舉例:[1,2], [2,5], [4,7], [3,6]
可以留下 [1,2] 跟 [3,6] 兩根香蕉,然後可以發現不可能留下三根或以上的香蕉,因此答案是 2
貪心法 = 猜 + 證明
習題
當貪心可以反悔
有 n 瓶藥水,每瓶藥水會給你的體力值增加或減少,你的體力一開始是 0,不能讓你的體力變負的,求最多能喝幾瓶藥水
藥水必須按照從前往後喝
考慮前 i 瓶藥水,必須滿足喝完之後體力不是負的
假設你已經有了 喝完前 i 瓶藥水的 [喝的藥水數量, 體力] 最大值
接下來選擇是第 i+1 瓶要不要喝
不喝的話已經知道結果了
喝的話,要是喝下去還是正的就直接喝
否則把最差的一瓶藥水挑出來,然後假設我其實沒有喝過他
發現了嗎 這就是後悔
再講一題
Work scheduling
習題
來玩遊戲吧
有一塊 n*m 的巧克力,每次選擇一條格線把巧克力剖成兩半,不能操作的玩家就輸了
有一塊巧克力,最左上角的格子有毒
兩個人每次可以選擇一個格子,並且把這個格子右下的所有巧克力吃掉,吃到毒的就輸了
求先手還是後手有必勝策略
Nim
有 n 堆石頭,每堆分別有 \( a_i \) 顆
你每次可以選擇其中一堆並拿取任意數量的石頭,不能拿的輸,求誰有必勝策略
例子
(3, 3)
(3, 6)
(1, 2, 3)
(3, 4, 5)
後手
先手
後手
先手
規律
把每堆的時候寫成二進位,然後 xor 起來
結果是 0 的時候就是後手必勝,反之先手必勝
xor 的結果稱為特徵值
要講為什麼之前 先來講賽局的定義
N: 先手必勝
P: 後手必勝
N:存在一個可以轉移到的盤面是 P
P:所有可以轉移到的盤面都是N
N:存在一個可以轉移到的盤面是 P
P:所有可以轉移到的盤面都是N
把他套上 Nim
要是當前 xor 不為 0,那我一定能把 xor 變成 0
要是當前 xor 為 0,那我怎麼做的 xor 都不是 0
為什麼?
P 只會轉到 N:每次操作會恰好改變一個數,亦即會改變特徵值
這裡用到的是 \(a \oplus b \neq a \oplus c \) 等價於 \(b \neq c\)
N 可以轉到 P:考慮特徵值的最高位
必定存在一個 \(a_i\) 滿足 \(a_i\) 的這個 bit 是 1
將他拿至剩 \(a_i\) \( \oplus\) 特徵值 即可
現在來玩賽局吧
假設有兩個賽局 \(G_1\) 與 \(G_2\)
定義 \( G_1 + G_2 \) 表示:雙方輪流選擇操作,每次的操作是選擇一個賽局 \( \in \{G_1,G_2\} \) ,然後做原本那個賽局的合法操作
等價
定義兩個賽局 \( G_1, G_2 \) 等價為
無論 \(H\) 是何賽局,\( G_1 + H \) 與 \( G_2 + H\) 的型別皆相同
記做 \( G_1 = G_2\)
性質
- 如果 \(G_1 = G_2\),那個他們型別相同
- 如果 \(G\) 屬於 P,那麼 \( H+G = H\)
- \(G_1\) 跟 \(G_2\) 都屬於 P \( \implies \) \(G_1 = G_2\)
1. 直觀
2. 分成 \(H\) 是先手必勝還是後手必勝來討論
要是 \(H\) 先手必勝,那先手會先拿 \(H\),就剩下兩個後手必勝的賽局
而先手的獲勝方式就是看對手拿哪個賽局就跟他拿一樣的賽局
3. 對任意賽局 \(H\),\(H+G_1 = H = H+G_2\)
根據等價關係,\(G_1 = G_2\)
性質
- 如果 \(G_1 = G_2\),那個他們型別相同
- 如果 \(G\) 屬於 P,那麼 \( H+G = H\)
- \(G_1\) 跟 \(G_2\) 都屬於 P \( \implies \) \(G_1 = G_2\)
定理:所有特徵值相同的 Nim 等價
證明:只需要注意到 \(G+G = 0\)
並且要是 \(G\) 與 \(H\) 特徵值相同那麼 \(G+H=0\)
\(H=H+(G+G)=(H+G)+G=G\)
接下來終於進入到最重要的理論了
Sprague-Grundy Theorem
每個標準無偏無環賽局都可以對應到一個 Nim 遊戲,意即都有一個特徵值
這個特徵值叫做 SG\((G)\)
決定 SG\((G)\) 的方法是枚舉下一步可能的賽局,將他們的特徵值取 mex
\(G+H\) 的特徵值就是 SG\((G)\) \(\oplus\) SG\((H)\)
mex
最小的不屬於集合中的非負整數
很抽象嗎
假設 Nim 有三堆石頭,分別有 1, 3, 4 顆
xor 起來是 6
我可以走到的狀態:
0, 3, 4
1, 0, 4
1, 1, 4
1, 2, 4
1, 3, 0
1, 3, 1
1, 3, 2
1, 3, 3
7
5
4
7
2
3
0
1
最小不存在的非負整數是 6
=>
=>
=>
=>
=>
=>
=>
=>
證明:
假設 \(G\) 的 SG value 為 x
賽局 \(H\) 為一堆剛好有 x 個石頭的 Nim
只需證 \(G+H=0\) 即可,也就是後手在 \(G+H\) 必勝
後面討論下去有點小複雜,這裡跳過
不能相鄰的遊戲
兩個人在一個 1*n 的方格表上輪流塗色,規定不能塗已經塗過的格子也不能塗與已經塗過的格子相鄰的格子,問誰獲勝
\(SG(n) = mex(\{SG(0) \oplus SG(n-2)\} \cup \{SG(i) \oplus SG(n-2-i) \mid 1 \leq i \leq n-3\})\)
有些 SG value 會循環
有時候可以猜猜看
1~n 的區域,有一些格子
有些格子已經被填入一個數字了
兩個人輪流操作,每次操作可以選擇 0 或是 1 放在任何一個沒有被放過的格子,但是不能使兩個相同的數字相鄰
沒有得放的輸
已知兩方都以最佳策略行動,求誰獲勝
在解題之前
首先要知道賽局的基本狀態是什麼
也就是哪些賽局彼此不會影響
可以發現,假設一串格子中間都是空白,兩端都有東西,會是一個互不影響的情況
因此把狀態設成 [空白的長度, 兩端狀態]
是個好選擇
來看小狀態的情況吧
空白長度 | 兩端相同 | 兩端不同 | 有一端有東西 | 都沒有 |
---|---|---|---|---|
0 | X | 0 | 0 | 0 |
1 | 1 | 0 | 1 | 1 |
2 | 1 | 0 | 2 | 0 |
3 | 1 | 0 | 3 | 1 |
4 | 1 | 0 | 4 | 0 |
規律: 1 0 n n % 2
空白長度 | 兩端相同 | 兩端不同 | 有一端有東西 | 都沒有 |
---|---|---|---|---|
0 | X | 0 | 0 | 0 |
1 | 1 | 0 | 1 | 1 |
2 | 1 | 0 | 2 | 0 |
3 | 1 | 0 | 3 | 1 |
4 | 1 | 0 | 4 | 0 |
競程
By alvingogo
競程
- 447