or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
競賽技巧 & 競賽介紹
Introduction to Competitive Programming
2/7
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →快讀/快出/換行 " \n"[i == n]
首先分析三種輸出輸入的優劣
C printf/scanf : 需要記%d %f %c %s 等等比較繁複的程式
C++ cin/cout : 較為簡單,不需處理資料類型,但比C標準輸入略慢一點
快讀/快寫 : 只能處理整數讀入/輸出,但是要比標準輸入輸出函數都快得多。
快讀
快寫
換行 " \n"[i == n]
不需要另外多寫if-else述句,可以
pragma GCC
只需要無腦加在最前面就好,原理為放棄編譯速度/運行速度/代碼大小/指標指向 去增加其他東西
實用且常用pragma
陣列開法(全域變數)&&const
const 是固定變數,你用const宣告出來的東西在之後就不能再更改,同時這樣開在全域就也不需要再函式間傳遞也不用考慮初始化的問題。
memset(arr,value,sizeof(arr))
時間複雜度是O(N),可以把整個arr的值都變成value。好處是方便快速,但可賦值有限制 ex: -1 , 0 , 0x3f3f3f3f
同時要使用則要記得引入標頭檔cstring
mt19937(hash<string>("
Image Not Showing
Possible Reasons
"))
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →如果要使用random等函式,不推薦在比賽中使用時間種子碼以及rand,而是推薦使用這個mt19937,產生高性能隨機數,且更為隨機以及可測試一點。
for(auto i : arr )
可以直接讓 \(i\) 遍歷 \(arr\) 裡面的東西,且auto也不用考慮型態,只需要無腦這樣寫,對於實作的方便性很高,直接讓編譯器宣告他的變數型態。
#define int long long
在你發現你的代碼需要把很多東西改型態的時候,只需要define這行就可以一次性把所有int變成long long,當然還有其他東西也可以這樣用。不過需要記得把main函數的定義改掉,改成int32_t或是signed都可以
ex :
__int128
與int,long long 沒什麼差別,特點有是超級大的定義域(可以儲存1e36內的數字),但C/C++標準IO是不認識__int128這種數據類型,cin和cout是無法輸出__int128的,所以我們要自己實現輸入輸出,其他的運算,與int沒啥差別。
__int128能直接做加减乘除赋值
begin, rbegin, end rend
c.begin() 返回一個迭代器,它指向容器c的第一個元素
c.end() 返回一個迭代器,它指向容器c的最後一個元素的下一個位置
c.rbegin() 返回一個逆序迭代器,它指向容器c的最後一個元素(比begin慢)
c.rend() 返回一個逆序迭代器,它指向容器c的第一個元素前面的位置(比end慢)
使用這些訪問方式,就可以不用去重新定義它的大小或是重新確認一次,同時也可以訪問那些沒辦法隨機存取的容器類別,可以直接叫出來。
prev, next
prev是指用來獲取一個距離指定迭代器左側 \(n\) 個元素的迭代器。
next是指用來獲取一個距離指定迭代器右側 \(n\) 個元素的迭代器。
假設現在有一個\(vector[10]={0,1,2,3,4,5} ; iter=2 ;\)
則會有以下四種
\(prev(iter,2), iter=0\)
\(prev(iter,-2), iter=4\)
\(next(iter,2), iter=4\)
\(next(iter,2), iter=0\)
就可以無需使用其他寫法去進行移動迭代器
int main(){ int T=1; //cin >> T; while(T–) solve(); }
就像是看到的那樣。
這樣的寫法可以讓你再換題的時候直接刪除solve函式,不須刪除其他東西,可以有效提高寫題目的效率。
大學競賽程式賽制介紹
各種比賽
見連結
比賽排名
先比解題數,再比penalty
那 penalty 怎麼算?
每題解出來的時間加起來,再加上多錯的次數*20
以此記分板來看 penalty 為 35 + 7 + 2*20 = 82
開場
一個人先打好 default code
通常為手速最快或者主要coder
其他人開始讀題目
通常為英文閱讀好、題目辨識難度強的人
為甚麼要先打 default code 呢?
殺首殺

每題要開始寫直接複製default code就好,減少寫程式碼量
看記分板 & 看別人的氣球
比賽中記分板,記得一定要定期刷新記分板,看大家解什麼題目
每題的氣球顏色都是固定的,因為記分板只能從電腦看,但如果隊友在上機看不了記分板就要觀察其他隊的氣球顏色
印code
比賽中隨時可以印出紙本code
那什麼時候要印
如果你是主coder 遇到bug
可以考慮給隊友找 自己再去開新的題目
評估題目
如果一次很多題目會寫,分析一下每題需要時間,根據greedy,先挑時間短的寫
比賽只有五小時,很短所以也要隨時注意時間
剩下一小時只留2~3題,最後半小時只留1~2題
補充血糖
比賽有五小時,很長XD
所以要定期去吃點心(建議1~2小時補充一次)
而且NCPC點心很好吃,很快就被搶光要搶要快(X
平常團隊訓練
養成良好分配習慣,知道彼此工作
賽後檢討彼此疏失或策略
修正策略
並且補題,也是最重要的,不補題跟沒打比賽一樣
不會解的題目還是不會
平常個人訓練
多打比賽,增加實作經驗
多寫題單,可以跟隊友溝通各自去練什麼演算法
多看電神的code,可以看到各種有趣精湛的寫法
各自專精擅長或有興趣的比賽也才能發揮各自所長
25 頁 A4單面紙本資料
DEBUG技巧
為什麼要學 linux 指令 ?
ICPC 國際大學生程式設計競賽
https://icpc2022.ntub.edu.tw/onsite/contest-environment/
NCPC 全國大專電腦軟體設計競賽
https://ncpc.ntnu.edu.tw/environment/final.html
如果我的電腦是 Windows ?
Windows Subsystem of Linux (WSL)
https://zhuanlan.zhihu.com/p/47541491
https://hackmd.io/@billsun/BJByCIUHf?type=view
linux 基本指令
編譯檔案
g++ solve.cpp -o main -std=c++14 -fsanitize=undefined -Wall -Wextra -Wshadow
其他編譯參數
g++ solve.cpp -o main -std=c++14 -fsanitize=undefined -Wall -Wextra -Wshadow
難道每次都要打那麼長嗎 ?
Alias
可以使用 alias 把原本要打的那串 define 掉
等同於 c++ 內的 #define
#define ll long long
使用 Alias 之後
等價於
產生質因數
debug
競賽中或者平常寫題目時,如果遇到 bug 不能及時找到
有以下方法
對拍
步驟
gen.py/gen.cpp
對拍的 script
先將兩份程式碼分別編譯成 ac, wa
不斷用
gen.py
產生測資放到 input 檔案裡面再把 input 檔案分別為給 ac, wa 兩份執行檔
用 for 迴圈一直跑到 output 內容不同為止
set -e 可以偵測程式 RE 時會停下來
跑到停下來後有兩種可能
為甚麼要用對拍
因此當比賽時,如果對於錯誤毫無頭緒,
不應該只是盯著程式碼看,而是開始寫對拍才是最有效率的做法
而平時練習、作業找不到bug的情況也應該要先對拍
真的找不到問題 對拍也對不到 再去問其他電神錯在哪
步驟
gen.py/gen.cpp
寫一份暴力程式碼 ac.cpp
聽起來好麻煩,為了 debug 還要多寫一份 code
而且不一定寫得出來還有可能錯,怎麼辦?
如果連暴力的程式碼都寫不出來 那你應該多練練你的實作能力…
如果不知道怎麼寫請參考早上 brute force 講義
善用 next_permutation 以及好好熟悉遞迴
沒有暴力寫不了的程式碼 只有你不練不夠實作能力
步驟
gen.py/gen.cpp
產生隨機測資 (python)
隨機產生一組 1~n 的 permutation
隨機產生一個長度為 n 的小寫字母字串
隨機產生一棵樹
每次從比自己小的節點選一個當連接自己的邊
隨機產生無自環無重邊的一張連通圖
無自環 可以判斷兩個點不相同
無重邊 可以用 dict/map 紀錄哪些邊用過了
連通圖 = 樹 + 一些額外的邊
隨機產生無自環無重邊的一張連通圖
產生隨機測資 (c++)
Don't use rand(): a guide to random number generators in C++
mt19937 是 c++ 的一種隨機產生器
sample code(c++)
練習產測資
隨便拿一場比賽練習每一題如何產測資
2023 I2CP Pretraining Final Contest
How to Debug ?
Debug –- Print 大法
可能有問題的那段程式碼 把變數 print 出來
這樣會有什麼問題 ?
1. debug 完 bug 忘記註解/刪掉
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →2. debug 完把 printer 註解,但沒有註解乾淨
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →3. 好麻煩喔 先把所有 cout 都註解la 再把要輸出的反註解
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →4. 喔 好像多註解到要輸出的答案了
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →這樣會有什麼問題 ?
penalty += 80(20 * 4)
cerr
debug 時,很常會用cout輸出每個變數的值
在這邊建議輸出debug的值時使用cerr
他輸出的東西只會出現在 Standard error stream
不會輸出在 Standard output stream
答案比對是比對 Standard output stream 的內容
因此就算忘記刪也不會造成影響
cerr 問題
如果沒有刪掉可能造成 TLE
原本可能 \(O(N)\) 的程式碼變成 \(O(N^2)\)
或者常數太大 (輸出數量變成原本的兩倍)
Debugging template
讓你更好 debug 的工具
#ifdef LOCAL
如果有 define LOCAL
那就會…
否則就會…
在本機 define LOCAL
則編譯時就會 define LOCAL
但每次都要打 -D LOCAL 很麻煩…
還記得 alias
改成
:happymention:
debug 變數
debug(x)
debug 範圍
orange(begin, end)
assert
他用來判斷一個條件是否成立,
如果條件成立則不會發生任何事
如果條件不成立,則會造成程式RE(Runtime Error)
通常用於 debug 不確定會不會錯
或者想 submit 時 不確定有沒有問題用的
或者想猜測資,判斷是否大於某個值,就可以assert
再加上 TLE 一起用
每次可以把測資分三半去猜測資 複雜度 \(O(log_3N)\)Benq's submission
Who is Benq?
比賽策略與準備