競程

建資 張庭瑋

什麼是競程

用演算法解決作者提出的問題,並以這個能力當作比賽的項目

大部分的人都是用 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

不用刷太多
感覺不會三不五時需要查語法的話就可以到下一個階段了

3. 可以來學演算法了

學的方式有很多,這裡只有講個人比較喜歡的

也就是跟著 CSES 刷 

搭配 book 食用

其他方式有很多 包含各個學長的講義都可以拿來用
效果應該都不錯

另外,這時候可以開始打各種比賽了

舉凡 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\)

性質

  1. 如果 \(G_1 = G_2\),那個他們型別相同
  2. 如果 \(G\) 屬於 P,那麼 \( H+G = H\)
  3.  \(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\)

性質

  1. 如果 \(G_1 = G_2\),那個他們型別相同
  2. 如果 \(G\) 屬於 P,那麼 \( H+G = H\)
  3.  \(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

競程

  • 348