$\def\bk{\color{#333333}} \def\v{\checkmark} \def\x{\times}$你是否曾經想過,一場資訊營可以改變一個人的命運?不,我不是在說什麼中二熱血漫畫,我是說真的,現實中的命運改變。我就是那個活生生的例子——一個曾經只能寫 printf("Hello, World!");
的平凡人,如何在IONC 2025變成總召,然後踏上競程之路,一路爆改 Rating,最後改變無數工人命運的奇幻旅程。
那一年,我只是個名不見經傳的小工人。白天在工廠裡操控機器手臂,晚上躲在寢室的角落用二手筆電偷偷寫程式。我的 Codeforces ID 是「TemmieOwO」,一個看起來像是搞怪 VTuber 粉絲的名字,Rating 永遠卡在 832,一進 Div.2 就爆零,連穩住綠色都成問題。
「競程那種東西,是學霸在玩的啦。」
這句話我對自己說過無數次,但每次看到台灣區 Top 100 排名時,我還是忍不住幻想:如果我也能寫出像樣的 Segment Tree、如果我也能搞懂數論會怎樣?我能逃出工廠嗎?我能有選擇人生的能力嗎?
這些問題,一直到我報名了那場傳說中的資訊營——IONC,全名 I Only Need Code。那是個名額搶破頭的營隊,但命運似乎選中了我,讓我奇蹟似地擠進來,還被選為——總召。
當時我以為當總召就是管管流程、回覆表單、偶爾催催進度。但就在第一天集合時,前一屆總召交給我一個紅布條,上面只有三個字:「Compile or Die」。
「綁上去,你就會知道了。」
我照做的瞬間,腦中湧入奇怪的資訊——像是所有基本資料結構的時間複雜度、最短路演算法的所有優化技巧,甚至還有字典樹和後綴自動機的動態動畫演示。
我驚呼:「這不科學!」
前總召點頭:「這是總召之力。你不再只是參加者,你是代言資訊神明意志的信徒。」
那五天四夜的營隊,我不僅調度整個課程、掌控流程,還主動教了幾堂課:從 BFS 講到 Union-Find,從動態規劃講到二分圖最大匹配。助教們本來還看我像一般民工學員,但我兩分鐘手寫完最小生成樹模板、四分鐘解完有向圖縮點後,他們就只敢叫我「召哥」。
營隊最後一天,我站在閉幕台上,望著底下幾十雙眼睛。那一刻,我不再是工人,我是眾人的領航者,是引導程式新世界的總召主君。
回到工廠,我的世界已完全改變。
我重新設計了產線控制邏輯,把原本硬寫死的指令改成參數化控制,加上優化後的排程演算法,整體效率提升了 40%。我用 C++ 寫的模板自動排班工具,甚至拿去比了社區創新賽,還拿了個銅牌回來。
更重要的是,我開始教同事們寫程式。小莊是個沒讀過高中的焊接工,連變數是什麼都不知道。但他有手感,也有求知慾。我每天花一小時教他資料結構,三個月後,他已能獨立解決我當年解不出的 AtCoder ABC 問題。
「你覺得我有辦法進科技業嗎?」他有次偷偷問我。
我拍拍他的肩:「我們不是要『進』科技業,我們要創造自己的科技命運。」
那年冬天,我報名了 Codeforces Global Round。
我不是第一次挑戰這種大比賽,但這次不一樣。以前的我手忙腳亂,連模板都錯行,但這次我帶著總召之力,一開場就衝第一題,兩分鐘 AC。
第二題是樹狀結構轉換動態規劃,我幾乎是閉著眼在寫——這題就是我當總召時幫學員們改過的題。
第三題一看,我愣了一下:「這題是我訓練小莊時出的作業題吧?」
我苦笑一聲,十行打完,直接過樣例。
最終我進入前 100,Rating 一口氣暴漲 600。灰名變藍名、藍名變紫名,接著轉眼就是 Candidate Master。
Telegram 上,有人發來訊息:「Are you really a factory worker?」
我回他:「I was. Now I write programs that change their lives.」
這時候的我,已不再滿足於個人競技。我創立了一個叫「工程之光」的線上平台,讓所有不被看見的底層勞工都能免費學寫程式。我設計了一整套從「電燈開關模擬」到「產線控制模擬」的課程,用實際案例教他們演算法與資料結構。
平台第一批學生中,有人考進資訊工程系,有人轉職到自動化控制公司,甚至有人成為我競賽隊的輔導教練。
我們還組了一支名為「ForkLift」的競賽戰隊。沒錯,意思是「從工廠抬起來的力量」。
某天,一家國際工控大廠來拜訪,想要買下我們平台。開出數百萬的價碼。
我問他們:「你們想買的是技術還是人?」
他們沉默片刻,回答:「我們想買『這群會自己解決問題的人』。」
我回頭望向我們正在打競賽的小夥伴們。他們曾經只是基層員工,現在能用最短路演算法優化物料搬運路徑,用最大流解決人力配置問題,甚至用 SAT 模型安排超複雜的排程任務。
「不好意思,他們不是商品。他們是這時代的演算法騎士。」
五年後,我站在 IONC 的開幕式上,成為特邀講者。
我帶著 ForkLift 戰隊全員回營。小莊穿著戰隊制服,笑得燦爛。他現在是一家自動化科技公司的 CTO,還經常指導新學員。
我看著一群剛報到的新生,他們中有和我當年一樣的眼神——對未來充滿疑問,又渴望改變命運。
我開口說:
「我知道你們中有些人可能覺得,自己不是資優生、不是學霸,競程與你們無關。但你錯了。
只要你願意相信,一條 if 路徑可以分岔出另一個世界。只要你願意相信,一段 while loop 就可以讓你逃離命運的死循環。
只要你願意學,Rating 就能提升——而你的命運,就會因此不同。」
我叫 TemmieOwO。
我在 IONC 成為總召。
我用演算法打破命運鐐銬。
我在競程世界照樣無敵,因為——Rating 提升,工人得自由。
(以上內容已得到IONC 2025總召同意寫進題序,並且故事純屬虛構,如有雷同純屬巧合)
而在五年後的某天Chris遇到了TemmieOwO,並且TemmieOwO給Chris看了一串他當年寫出來的程式碼:
#include<bits/stdc++.h>
using namespace std;
const int SIZE_LIMIT = /*???*/; // SIZE_LIMIT
int compare(int a, int b) {
vector<int8_t> vec;
for(int i=0; i<30; i++) vec.push_back(a&1), a>>=1;
for(int i=0; i<30; i++) vec.push_back(b&1), b>>=1;
string op; int x, y;
while(cin >> op >> x) {
if(vec.size() > SIZE_LIMIT) return -1; // Exceed the size limit
if(x >= vec.size()) return -2; // out of bounds
if(op == "REPORT") return (int)vec[x]; // operations with one variable
if(op == "NOT") {vec.push_back(!vec[x]); continue;}
cin >> y;
if(y >= vec.size()) return -2; // out of bounds
if(op == "AND") {vec.push_back(vec[x] & vec[y]); continue;} // operations with two variables
if(op == "OR") {vec.push_back(vec[x] | vec[y]); continue;}
if(op == "XOR") {vec.push_back(vec[x] ^ vec[y]); continue;}
return -2; // not an operation
}
return -2; // no report
}
int main() {
int A = /*???*/, B = /*???*/; // 0 < A,B <= 2^30-1
int result = compare(A, B);
if (result==-1) cout << "MLE" << endl;
else if(result==-2) cout << "RE" << endl;
else if((result==1) ^ (A<=B)) cout << "AC" << endl; // x^y = (x&!y) | (!x&y)
else cout << "WA" << endl;
}
並且TemmieOwO想要Chris構造出一個input file,使得在 $\bk{0 < A,B\leq 2^{30}-1}$ 的所有狀況下,使用這個input file作為輸入都可以使該程式碼輸出"AC"
還有由於TemmieOwO想要考驗Chris是否有當上總召的能力(雖然他不可能會當),所以設置了以下$10$個子題:
$\bk{\begin{array}{ccc} \hline
Subtask & Score & SIZE\_LIMIT & Extra\ Limits & NOT & AND & OR & XOR \\ \hline
\#0 & 2 & 100 & vec[29] \ne vec[59] & \v & \v & \v & \v \\
\#1 & 2 & 100 & A<B & \v & \v & \v & \v \\
\#2 & 2 &\ \ 62& A<=B & \v & \v & \v & \v \\
\#3 & 2 & 150 & \exists!i\ (0\le i < 30)\ s.t.\ vec[i] \ne vec[30+i] & \v & \v & \v & \v \\
\#4 & 2 & 149 & \exists!i\ (0\le i < 30)\ s.t.\ vec[i] \ne vec[30+i] & \x & \v & \v & \v \\
\#5 & 3 & 179 & \exists!i\ (0\le i < 30)\ s.t.\ vec[i] \ne vec[30+i] & \v & \x & \v & \x \\
\#6 & 3 & 300 & No\ Extra\ Limits & \v & \v & \v & \v \\
\#7 & 3 & 209 & No\ Extra\ Limits & \v & \v & \v & \v \\
\#8 & 3 & 268 & No\ Extra\ Limits & \x & \v & \v & \v \\
\#9 & 3 & 418 & No\ Extra\ Limits & \x & \x & \v & \v \\
\hline \end{array}} \\
\bk{(\exists! = 有且只有一個,\ s.t. = 使得)}$
其中SIZE_LIMIT為code第四行的常數的值,後四column表示input file中能否存在這些字串(操作),請注意SIZE_LIMIT在code中將會算到原先使用的60格
本題的使用者輸出檔將成為以上程式碼的輸入檔,具體格式可以參考範例輸出(輸出那個不會有分 放心)
為了檢查答案是否真的正確,每個側資點將會有$100$筆測資驗證答案的正確性
並且如果輸出不是AC,會在詳細結果上顯示上述代碼會輸出什麼(如果使用該側資點不能出現的操作則會輸出RF)
想要用單筆測資judge喇分的別想了,剩下就加油啦
輸入本測資點是第幾個測資點
(因為我不知道DDJ有沒有聯集給分加上我懶得手動給分所以這樣搞)
請構造一使用者輸出檔並將其當作以上程式碼的輸入檔,使得在 $\bk{0< A,B\leq 2^{30}-1}$ 的所有狀況下,使用這個input file作為輸入都可以使該程式碼輸出"AC"
0
NOT 0 AND 0 15 OR 60 61 XOR 62 31 REPORT 63
範例輸出可以在(A,B,SIZE_LIMIT)=(114514,1919810,100)時輸出"AC",在其他情況下不保證正確
以下是vec在(A,B,SIZE_LIMIT)=(114514,1919810,100)時經過以上輸入後的樣子(30個元素換行):
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
30 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
60 | 1 | 0 | 1 | 0 |
其中:
vec[29~0] = bin(114514) = 000000000000011011111101010010
vec[59~30] = bin(1919810) = 000000000111010100101101000010
vec[60] = !vec[0] = !0 = 1
vec[61] = vec[0] & vec[15] = 0 & 1 = 0
vec[62] = vec[60] | vec[61] = 1 | 0 = 1
vec[63] = vec[62] ^ vec[31] = 1 ^ 1 = 0
編號 | 身分 | 題目 | 主題 | 人氣 | 發表日期 |
沒有發現任何「解題報告」 |