# AA 競程問問題教學 ## 為什麼要學會問問題? 問問題是學習競程很重要的一環。好的提問方式能讓老師**更快幫你找到問題**,也能訓練你自己的除錯能力。很多時候,在整理問題的過程中,你就會自己發現答案了。 反過來說,如果你丟一段程式碼然後只說「這題不會」或「幫我看哪裡錯」,老師需要花很多時間重新理解你的思路,回覆速度會慢很多,對你的學習效果也比較差。 ## 我可以在哪裡問問題? 1. 在 Discord AA 競程伺服器討論區問問題 2. 在 Discord 私訊詢問老師 --- ## 類型一:詢問自己的程式碼錯在哪 ### 必要資訊 **1. 附上題目名稱及連結** 讓老師能直接點進去看題目,不用自己搜尋。 > ABC368 A - Cut > https://atcoder.jp/contests/abc368/tasks/abc368_a **2. 附上你的程式碼** 選擇以下任一方式: - **方式一:附上 Judge 上的提交紀錄連結**(推薦,最方便) - AtCoder:https://atcoder.jp/contests/abc368/submissions/63486440 - Codeforces:https://codeforces.com/contest/1814/submission/309472479 - AACPOJ:https://aacpoj.com/submission/16800 - CSES:https://cses.fi/paste/1a64e2970f1efa8f8febea/ (這是 submission detail 頁面點 Share code to others 產生的頁面,注意此頁面不會顯示評測結果,要另外告知對方錯誤類型) - TIOJ、NCOJ 無法在網站上看到其他使用者上傳的程式碼,請使用其他方式附程式碼 - 注意:Codeforces 要參加過至少一場比賽才看得到別人的程式碼;EDU 的題目只能看到自己的紀錄 - **方式二:直接貼程式碼在 Discord 上,並使用語法高亮** 在程式碼前後加上 \`\`\`cpp 和 \`\`\`,像這樣: ```` ```cpp #include <bits/stdc++.h> using namespace std; int main() { int n, k; cin >> n >> k; // ... } ``` ```` - **方式三:使用線上分享工具** 把程式碼貼在 https://pub.akr.tw/simple.html?pid=自訂id 後,直接貼連結給老師。 **3. 告知錯誤類型** 說明你得到的是哪種錯誤:WA、TLE、RE、MLE 等。如果提交紀錄連結裡已經顯示了,就不需要額外說明。 若是 WA,進一步說明是哪幾個子任務沒過、或是全部都錯,這能幫助老師判斷你的做法是方向錯了還是只有邊界沒處理好。 ### 問之前請先自行檢查 **4. 確認自己已經檢查過「競程四大常見錯誤」** 在提問時宣示你已經逐一檢查過以下四項: | 常見錯誤 | 檢查方式 | |---|---| | 忘記開 `long long` / 整數溢位 | 想想中間計算過程會不會超過 $2^{31}-1$(約 $2 \times 10^9$) | | 陣列開太小 / 存取到錯誤的記憶體位置 | 對照題目的範圍限制,確認陣列大小足夠;注意 0-indexed 和 1-indexed | | 忘記初始化 / 初始化錯誤 | 特別注意多筆測資時,變數和陣列有沒有在每次測資開始時重新初始化 | | 極端值沒有處理 | 想想 $N=0$、$N=1$、全部相同、最大值等邊界情況 | **5. 宣示自己已經嘗試過用小測資除錯** 試著自己造幾組小測資手動跑,看能不能找到一組讓你的程式輸出錯誤答案的測資。如果都找不到,告訴老師「我試過了以下幾組測資都是對的,找不到會錯的情況」。 **6. 若不是使用老師教的做法,請解釋你的思路** 如果你的解法和上課教的不一樣,老師不一定能一眼看出你在做什麼。請用文字簡單描述你的演算法,或是在程式碼中加上註解。 ### 範例:好的提問 vs 不好的提問 **不好的提問:** > 老師這題錯了幫我看 > (貼一段沒有語法高亮的程式碼) **好的提問:** > 老師,我在寫 ABC368 A - Cut(https://atcoder.jp/contests/abc368/tasks/abc368_a) > > 我的提交:https://atcoder.jp/contests/abc368/submissions/63486440 > > 得到 WA,錯在第 3 個子任務。 > 我已經檢查過四大錯誤,也試了 N=1 和 N=最大值的測資都是對的,找不到會出錯的情況。 > > 我的做法是:先把後 K 個元素存起來,再把前 N-K 個接在後面輸出。 ### 問題解決後 **7. 若問題已獲得解決,請告知對方** 不管是老師幫你解決的,還是你後來自己想到的,都請回覆一下讓老師知道這個問題已經結束了。這是基本禮貌,也讓老師知道不用再花時間想你的問題。 --- ## 類型二:詢問不會做的題目的做法 ### 問之前請先自己嘗試 直接問「這題怎麼做」而沒有經過任何思考,對你的學習幫助很小。請先經過以下步驟: **1. 如果是老師上課教過的題目** 請描述你哪個部分沒聽懂,或是從哪一步開始沒聽懂。 > 老師,上課講的那題最長遞增子序列,我理解為什麼要用 DP,但是不懂為什麼轉移式是取 max 而不是直接加 1。 **2. 如果是上課沒教的習題** 請先嘗試以下方法: - 讀題目的**官方題解**(Editorial) - 上網搜尋其他參賽者寫的**題解報告**(例如搜尋「ABC368 題解」) - 嘗試用你已經學過的演算法去套用 **3. 如果官方解答或題解看不懂** 請描述你**從哪裡開始看不懂**,而不是只說「看不懂」。 > 老師,我看了這題的官方題解,它說要用線段樹維護區間最大值,我知道線段樹的基本操作,但不懂它怎麼處理「區間修改」的部分,題解寫的 lazy propagation 我看不太懂。 **4. 如果你有自己的想法但不確定對不對** 可以先描述你的想法,問老師方向是否正確,這比從零開始問好很多。 > 老師,這題我覺得可以用 BFS 做,但我不確定要怎麼處理邊權不同的情況,是不是要改用 Dijkstra? **5. 如果懷疑老師預期的做法和官方題解不一樣** 也可以直接向老師詢問,有時候老師會用比較適合目前學習進度的做法來解題。 --- ## 類型三:詢問觀念或演算法 如果你對某個觀念或演算法有疑問,請盡量具體描述你的困惑。 **不好的提問:** > 老師,我不會 DP。 **好的提問:** > 老師,我理解 DP 的概念是把大問題拆成小問題,但我在寫背包問題的時候,不懂為什麼要從大到小遍歷重量,如果從小到大會怎樣? **提問的關鍵:說出你「已經知道什麼」和「從哪裡開始不懂」。**這樣老師才能從你卡住的地方開始解釋,而不是從頭講起。 --- ## 通用原則 ### 提問前的自我檢查清單 - [ ] 我有附上題目連結嗎? - [ ] 我有附上程式碼(且格式清楚)嗎? - [ ] 我有說明錯誤類型嗎? - [ ] 我有自己嘗試除錯 / 思考過嗎? - [ ] 我有描述我的思路和卡住的地方嗎? ### 幾個好習慣 1. **不要只傳截圖**:程式碼請用文字形式傳送(方便老師複製來測試),截圖只適合用來補充說明(例如呈現錯誤畫面)。 2. **善用搜尋引擎與 AI**:很多問題自己就能找到答案,不需要等老師回覆: - **Google**:基礎語法問題(例如「C++ sort 怎麼用」)直接搜尋就有。 - **ChatGPT / Claude 等 AI**:可以拿來問語法、解釋錯誤訊息、幫你看某段程式碼為什麼會 RE 等。把你的程式碼和題目敘述貼給 AI,它通常能很快指出問題。 - **但要注意**:AI 給的演算法解法不一定正確,尤其是比較難的題目,它可能會講得頭頭是道但邏輯是錯的。拿 AI 來除錯和理解語法很好用,但拿它來替你想解法會讓你失去練習思考的機會。建議的使用方式是**先自己想過,卡住時再用 AI 輔助理解**,而不是直接叫 AI 幫你解題。 3. **記錄你問過的問題和答案**:下次遇到類似的問題時,先翻翻自己的筆記。 4. **問題解決後回覆一聲**:讓老師知道問題已解決,這是基本禮貌。