算法竞赛

**演算法競賽**（又稱編程競賽、信息學競賽、程式設計競賽），不同於駭客松是一項智力運動，通常在網際網路上或區域網上舉行，其內容包括參與者嘗試根據提供的要求進行撰寫程式碼 。 參賽者被稱為_競賽程式員_ 。演算法競賽得到了多家跨國軟體和網際網路公司的認可和支持，例如 Google 和 Facebook。

演算法競賽通常涉及到主辦方向參賽者提出一組邏輯或數學問題（參賽者的數量可能從幾萬到數千不等），並且要求參賽者編寫能夠解決每個問題的電腦程式。評測主要基於解決的問題數量和編寫成功解決問題的程式所花費的時間，但也可能包括其他因素（產生的輸出品質，執行時間，程式大小等）。

## 歷史

已知的最古老的競賽之一是國際大學生程式設計競賽，該競賽起源於 1977 年，2011 年中參賽者範圍已經擴大到 88 個國家 / 地區。自從 2000 年以來，它也同時與 Internet 的發展有了很強的聯繫。這促進了在網上舉辦比賽，同時也消除了地理性的問題。

## 概述

演算法競賽的目標是編制原始碼，在有限的計算資源內來解決給出的問題。大部分的問題是屬於數學問題或者邏輯學問題。它們通常屬於下面幾個類型中的一個：組合數學、數論、圖論、幾何（很多時候是計算幾何）、字符串和資料結構。和人工智慧相關的內容在某些比賽中也很會出現。

不論問題的類別，解決問題的過程都可以大致地分為兩大步驟：構思一個演算法，以及使用一個程式語言來實現演算法（允許使用的語言每個競賽都會不同，主要以 C++，Java，Pascal 等為主，但是 IT 企業的競賽大多會使用該企業的常用語言）。

大多數競賽中，選手只應該為每一題編寫一個原始碼，這個原始碼的系統調用會受到限制。一般創建新進程，訪問網絡，操作無關文件等等都是不允許的。一般情況下，選手只能使用他 / 她所使用的語言的標準庫（例如 C++ 語言的 STL）。

一道傳統的題目由以下幾個部分組成。下面使用大多數 OJ 使用的試機題目 A+B 問題來做簡要的闡述：

## 試題

在一般的競賽中，試題有以下幾種。

* **傳統題**要求程式從輸入讀入一些數據，進行求解後輸出，這是最常見的題目。
* **提交答案題**會事先下發輸入數據，選手需要通過任意方法（包括計算器、手算、編寫程式等）進行求解，並提交答案文件。
* **互動題**會讓選手程式與互動系統進行互動，一般會通過輸入輸出或者調用給定函數庫來實現。例如 NOI 2019. I 君的探險 （頁面存檔備份，存於網際網路檔案館）
* **通信題**要求選手編寫兩個相互協作的程式解決問題。例如 UER #8. 打雪仗 （頁面存檔備份，存於網際網路檔案館）

## 賽制與測評

在大多數競賽中，評測是通過主辦者的計算機進行的，這通常稱為裁判系統。裁判會對選手提交的代碼通過一組（通常是秘密的）測試數據進行測試。測試方法是所謂的**黑箱測試**，也即，裁判不關心選手的程式是如何實現的，而只要求它能夠在規定的限制內正確地解答出問題。

大多數競賽中，選手在提交代碼之後能夠即時獲取反饋，一般反饋分為以下幾種：

* AC (Accepted)：通過，選手程式完成了任務。
* PE (Presentation Error)：輸出格式錯誤，選手程式輸出答案正確，但是格式錯誤（例如，行中間出現空格），在某些競賽中被視作 WA。
* WA (Wrong Answer）：答案錯誤，選手程式儘管成功運行，但並沒有成功求解問題。
* TLE (Time Limit Exceeded)：超出時間限制，選手程式運行時超出了題目給出的時間限制。
* MLE (Memory Limit Exceeded)：超出空間限制，選手程式所使用的空間超過了題目給出的內存限制。在極少數競賽中（例如 USACO）被視作 RE。
* RE/RTE (Runtime Error) ：運行時錯誤，選手程式崩潰。
* OLE (Output Limit Exceeded) ：輸出超過限制，選手程式輸出了過多內容。
* CE (Compile Error) ：編譯出錯，選手程式沒有成功編譯。
* IE/SE (Internal Error/System Error) ：內部錯誤，評測系統出錯。這時選手應當報告比賽主辦方。某些平台細分為多種 （例如 Compilation Failed 編譯器錯誤， Denial of Judgement 拒絕評測，Judgement Failed 評測失敗，Checker Crashed 比較器崩潰等）。

另一些競賽 （例如 NOI）不提供即時反饋。系統在競賽結束後會統一評測。

有些競賽只有「對」和「不對」之分，沒有部分分。例如 ICPC。而另一些競賽會按照測試點或者子任務分別給分。有時，還會按照解的優劣性進行部分給分。

對於傳統題，一般判斷答案正確的方法是在過濾行末空格和文末回車之後逐行比對，但是，有的題目會使用特製的比較器來進行測評。對於其他類型的題目則一般通過比較器進行給分。

大多數競賽要求選手程式從標準輸入讀入數據，將答案寫到標準輸出，而早期競賽和 NOI 系列賽則要求選手從給定的輸入文件讀入數據，將答案寫到輸出文件。

## 主要競賽

比賽分為短期和長期兩種。

### 短期

中國

* NOI - 中國 自 1984 年起舉辦的競賽。

香港

* 香港電腦奧林匹克 - 香港 自 1997 年起舉辦的競賽

台灣

* 高級中學數理及資訊學科能力競賽 - 臺灣 自 1999 年起舉辦的競賽
* 臺灣國際奧林匹亞競賽 - 臺灣用於選拔國際資訊奧林匹亞選手的比賽，由國立臺灣師範大學資訊工程學系主辦

國際 / 其他地區

* 國際大學生程式設計競賽 (ICPC) - 歷史最悠久的競賽之一，由大學生三個人組隊參加；
* CodeChef - 從 2009 年起，每個月會有兩場短競賽 和每年一場的 CodeChef SnackDown；
* Codeforces Round - 一般是兩小時，每星期舉行；
* Facebook Hacker Cup - 由 Facebook 提供和支持的競賽；
* HackerRank - 數種競賽；
* Google Code Jam - 由 Google 提供和支持的競賽
* IEEEXtreme Programming Competition - IEEE 為其學生會員舉辦的競賽。
* 國際信息學奧林匹克 - 面向中學生的最古老競賽之一。

上述大多數競賽都按輪舉行，在 NOI, IOI, ICPC 等競賽中，獲得好成績的選手可以獲得金牌、銀牌或銅牌。

### 長期

* HackerRank Week of Code
* Topcoder 馬拉松

## 在線資源

有許多線上解題系統可以提供訓練資源。以下僅列出較常見的評測系統。

### 非中國地區

* **Codechef** 是印度的線上解題系統，也提供比賽。
* **AtCoder** 是日本的線上解題系統，提供比賽。
* **Codeforces** 是俄羅斯的評測系統，提供比賽。
* **UVa** 是西班牙的評測系統，收錄了大量 ICPC 的真題，題目品質較高。現在已經去掉了這個名稱而直接叫做 **Online Judge**。
* **SPOJ** 是波蘭的評測系統。
* **SZKOPUL** 收錄了波蘭信息學奧林匹克的很多試題。

### 中國地區

* **POJ** 是北京大學的評測系統。收錄了不少亞洲區 ICPC 真題。
* **ZOJ** 是浙江大學的評測系統。
* **LibreOJ** 是由網名 Menci 的 OI 選手維護的線上解題系統，理念是自由開放。
* **UOJ** 是由網名 vfleaking 的 OI 選手維護的線上解題系統，理念是接受一切試題的評測。
* **評測鴨**是由王逸鬆開發的評測系統，能夠將時間計算精確到奈秒。
* **洛谷**是上海洛谷網絡科技有限公司的評測系統，提供收費的網校服務。
* **香港電腦奧林匹克競賽網上評測系統 (HKOI Online Judge)** 原為集訓隊的訓練平台，現已開放予全港中學使用。
* **AcWing** 是北京睿新奇知科技有限公司旗下品牌，擁有優秀的演算法在線課堂，以及 AC Saber。

### 臺灣地區

* **Zerojudge** 是台灣最大的評測系統，題目來源較為廣泛。
* **Green Judge** 是由台中女中建立的評測系統，以新手向題目為主
* **TIOJ** 是建國中學的評測系統。

## 參考文獻