<style> .reveal .slides { font-size: 40px; } </style> # 南大附中資訊研究社 NFIRC 1st ## 第 4 次社課講義 2023/11/22 主講:劉正宗 老師 ---- ## 課前準備 - 開好上課需要的頁面 - Discord - Google Meet - Replit - Zero Judge - 點名 - 社團積分 --- ## 複習時間 - 變數 - 運算子 - 條件判斷式 ---- ## 變數大集合 | 名稱 | 寫法 | 備註 | | ------- | -------- | -------- | | 整數 | int | 範圍 $-2^{31}$ ~ $2^{31}-1$ | | 較大的整數| long long| 範圍 $-2^{63} \sim 2^{63} - 1$| | 浮點數 | double | 儲存非整數的時候使用 | | 字元 | char | 以 '' 包住字元 | | 字串 | string | 以 "" 包住字串 | | 布林值 | bool | 僅有兩個值:true / false| ---- ## 保留小數點的除法 - 強制轉型 寫法是括號內包住要轉變的型別 ![image.png](https://hackmd.io/_uploads/SkIcd1dmp.png) ---- ## 全域變數&區域變數 ![image.png](https://hackmd.io/_uploads/BJtR9x4Qp.png) ---- ## bool 布林值 + true == 1 + false == 0 ---- ## 比較運算子 | 定義 | 運算子 | 解釋 | | -------- |:------:|:--------------------------- | | 相等 | == | a 與 b 相等 50 == 50 | | 不相等 | != | a != b 就像 50 != 100 | | 大於 | > | a > b 就像 100 > 50 | | 小於 | < | a < b 就像 50 < 100 | | 大於等於 | >= | a >= b 就像 100 >= 50 | | 小於等於 | <= | a <= b 就像 50 >= 100 | ---- ## 邏輯運算子 ```typescript 或(OR): || 且(AND): && 相反(NOT): ! ``` [詳細介紹文章 by SA](https://hackmd.io/@sa072686/cp/%2F%40sa072686%2FHkfY_rMur) ---- 條件判斷式 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; if(n > 0) cout << 1 << "\n"; else if(n == 0) cout << 0 << "\n"; else cout << -1 << "\n"; return 0; } ``` ---- ## 延伸知識 - [int 的範圍 溢位 開 long long](https://hackmd.io/@sa072686/cp/%2F%40sa072686%2FB1tr_OtOS) - 有號無號 signed & unsigned - INT_MIN, INT_MAX - min( ), max( ) - 小數點後位數 setprecision( ) - [浮點數的誤差與應對](https://hackmd.io/@sa072686/cp/%2FcZfev35MRp-nFy_YII9wfg) - 三元運算 (A ? B : C) - [多條件判斷式 switch](https://openhome.cc/Gossip/CppGossip/switchStatement.html) --- ## 目錄 1. while 迴圈 2. for 迴圈 3. 迴圈控制 (continue、break) 4. 延伸知識 ❗️原訂內容有教陣列 但因此次上課沒上完 所以目前已將陣列內容移到下一次第 5 次社課教 ---- ## 課前須知 此次上課相比之前的社課 會有更多的程式碼出現在講義中 希望培養大家閱讀程式碼的能力 試著理解每段 Code 的運作原理 能更有效提升你的程式能力 --- ## 迴圈 1. while 2. for ---- ## 迴圈是什麼? ![image-removebg-preview](https://hackmd.io/_uploads/Hyv9aB8ET.png) 重複執行 ---- ## 說 100 次 hello ```cpp= #include <iostream> using namespace std; int main() { cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; cout << "hello\n"; return 0; } ``` ---- ## 一定要複製 100 次嗎? ---- 我們可以使用迴圈 讓電腦幫我們重複執行 100 次就好 不用我們自己複製 100 行程式碼 --- ## while 迴圈 當條件成立時 重複執行直到條件不成立 ```txt= while(條件成立時) { 重複執行這段程式碼 } 條件不成立時 電腦會退出迴圈並接著執行下面的程式 ``` ---- ## 如何用 while 迴圈說 100 次 hello ```cpp= #include <iostream> using namespace std; int main() { int t = 100; while(t > 0) { cout << "hello\n"; t--; } return 0; } ``` ---- ## 無限迴圈 ![image-removebg-preview (1)](https://hackmd.io/_uploads/ByYzWLIEp.png) 當條件永遠成立時 將會形成無限迴圈 ---- ## 重複無限次說 hello ```cpp= #include <iostream> using namespace std; int main() { while(true) { cout << "hello\n"; } return 0; } ``` :::danger 請極力避免寫出無限迴圈 ::: ---- ## 如何避免寫出無限迴圈 ### 修改前 ```cpp= #include <iostream> using namespace std; int main() { int t = 100; while(t > 0) { cout << "hello\n"; } return 0; } ``` 因為每次做完迴圈中的事後 t 並沒有改變 條件永遠成立 所以會無限重複做下去 ---- ### 修改後 ```cpp= #include <iostream> using namespace std; int main() { int t = 100; while(t > 0) { cout << "hello\n"; t-- // 讓條件中的 t 每次都遞減 才有機會退出迴圈 } return 0; } ``` ---- ### 簡化版 ```cpp= #include <iostream> using namespace std; int main() { int t = 100; while(t--) { cout << "hello\n"; } return 0; } ``` 因為在上一堂課有教到 bool 布林值 true == 1 false == 0 當 t 逐漸遞減到 0 時 剛好就是條件不成立的 false 就會退出迴圈了 ---- ## 使用 while 讀取特定數量的輸入 有 n 個數字 請讀入那 n 個數字後 輸出總和 輸入 ```txt 5 10 40 20 80 50 ``` 輸出 ```txt 200 ``` ---- 輸入 ```txt 5 10 40 20 80 50 ``` 程式碼 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int n, a, sum = 0; cin >> n; while(n--) { cin >> a; sum += a; } cout << sum << "\n"; return 0; } ``` ---- 當題目沒有說有幾個數字時 你該怎麼辦 ```txt 10 40 20 80 50 ``` 輸出 ```txt 200 ``` ---- ## 重要技巧 EOF EOF(End Of File) 當題目沒有限制有幾筆輸入時 我們只好重複輸入直到沒有輸入為止 此技巧在競程題目中常常出現 請務必學會 ---- 輸入 ```txt 10 40 20 80 50 ``` 程式碼 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int n, sum = 0; while(cin >> n) { sum += n; } cout << sum << "\n"; return 0; } ``` ---- ## 解釋 cin 這個函式其實是會回傳 bool 的 如果正確讀取到了整數會回傳 true 沒有讀取到東西就會回傳 false 所以我們把 cin 放在 while 的條件裡 剛好就能在沒有讀取到數字時退出迴圈 ---- ## 如何判斷整數有幾個位數 輸入 1 ```txt 100 ``` 輸出 1 ```txt 3 ``` 輸入 2 ```txt 12345678 ``` 輸出 2 ```txt 8 ``` ---- 需運用到 1. while 迴圈 2. 除法 ---- ## 求位數程式碼 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int n; cin >> n; int digit = 0; while(n != 0) { n /= 10; digit++; } cout << digit << "\n"; return 0; } ``` --- ## for 迴圈 重複執行特定次數 ```txt for(初始值; 判斷式; 改變值) { 重複執行這段程式碼 } ``` ---- ## 請輸出 1 ~ 10 如果沒學迴圈你可能會這樣寫 ```cpp= #include <iostream> using namespace std; int main() { cout << 1 << " "; cout << 2 << " "; cout << 3 << " "; cout << 4 << " "; cout << 5 << " "; cout << 6 << " "; cout << 7 << " "; cout << 8 << " "; cout << 9 << " "; cout << 10 << " "; return 0; } ``` ---- ## 用 for 迴圈解決 ```cpp= #include <iostream> using namespace std; int main() { for(int i = 1; i <= 10; i++) { cout << i << " "; } return 0; } ``` ---- ## 請輸出 10 ~ 1 ```cpp= #include <iostream> using namespace std; int main() { for(int i = 10; i > 0; i--) { cout << i << " "; } return 0; } ``` 只需把 for 迴圈中的三個地方調整一下就好 1. 把初始值設成最後一個 2. 把判斷式改成 i > 0 3. 把變化量改為 遞減 ---- ## 如何用 for 迴圈說 100 次 hello ```cpp= #include <bits/stdc++.h> using namespace std; int main() { // 設 i 從 0 開始; 當 i < 100 時繼續執行; 每做完一次 i 就 +1 for(int i = 0; i < 100; i++) { cout << "hello\n"; } return 0; } ``` ---- ## 如何在 n 個數字中找最大或最小值 輸入 ```txt 5 55 16 40 84 136 ``` 輸出 ```txt max = 136 min = 16 ``` ---- 各位可以聯想到利用上一節的延伸知識中 max()、min() 函數與 INT_MAX、INT_MIN 在每次的輸入後判斷最大最小值 ---- 程式碼 ```cpp= #include <iostream> using namespace std; int main() { int maxn = INT_MIN, minn = INT_MAX; int n,a; cin >> n; while(n--) { cin >> a; maxn = max(maxn, a); minn = min(minn, a); } cout << "max = " << maxn << "\nmin = " << minn << "\n"; } ``` 先把最大值設成一個很小的值 int maxn = INT_MIN 在每次輸入時都比較一次 maxn = max(maxn, a); 輸入完就會是最大值了 最小值同理 ---- ## 觀察到了嗎 迴圈其實就是把重複、單一、的事情 交給電腦重複跑 省時省力 --- ## 迴圈的控制 - continue - break ---- ## 請輸出 1 ~ 10, 但不要輸出 n 如果 n == 3 請輸出 ``` 1 2 4 5 6 7 8 9 10 ``` 如果 n == 8 請輸出 ``` 1 2 3 4 5 6 7 9 10 ``` 思考一下該怎麼做呢? ---- ## 用兩個迴圈? ```cpp= #include <iostream> using namespace std; int main() { int n; cin >> n; for(int i = 1; i < n; i++) { cout << i << " "; } for(int i = n+1; i <= 10; i++) { cout << i << " "; } return 0; } ``` ---- 太麻煩了 我們來學 continue continue == 繼續(跳過此次) ---- ## continue 實際應用 請輸出 1 ~ 10 但不要輸出 n ```cpp= #include <iostream> using namespace std; int main() { int n; cin >> n; for(int i = 1; i <= 10; i++) { if(i == n) { continue; } cout << i << " "; } return 0; } ``` ---- ## 請加總 1 ~ 10, 在超過 n 前就停止 如果 n == 8 請輸出 ``` 1 2 3 ``` 如果 n == 20 請輸出 ``` 1 2 3 4 5 ``` 思考一下該怎麼做呢? ---- n == 8 ```cpp= #include <iostream> using namespace std; int main() { int n, sum = 0; cin >> n; for(int i = 1; i <= 10; i++) { if(sum + i > n) { break; } cout << i << " "; sum += i; } return 0; } ``` 輸出 ``` 1 2 3 ``` ---- 適當的運用迴圈與控制可以事半功倍 讓你寫程式更有效率、更有邏輯 --- ## 延伸知識 - do-while 迴圈 ---- ## do-while 迴圈 - while:重複執行直到條件不成立 (當一開始條件不成立時就完全不會執行) ```cpp= while(條件成立時) { 重複執行這段程式碼 } ``` - do-while:先執行一次再重複執行直到條件不成立 (必定會先執行一次 再決定是否繼續) ```cpp= do { 程式碼 } while (條件成立時才繼續重複執行程式碼直到條件不成立); ``` ---- ## 使用 do-while 加總 1 ~ 100 ```cpp= #include <bits/stdc++.h> using namespace std; int main() { int sum = 0, i = 1; do { sum += i; i++; } while (i <= 100); cout << "1 + 2 + .... + 99 + 100 = " << sum << "\n"; return 0; } ``` --- # 題單 ## 必做 1. [d498 迴圈](https://zerojudge.tw/ShowProblem?problemid=d498) 2. [a104 陣列 排序](https://zerojudge.tw/ShowProblem?problemid=a104) # ### [題解連結](https://nfirc.notion.site/c1db904ca8604f62918c204da938dc51?v=ff8e808739744ad8bb195ef63ee348f2&pvs=4) --- ## 回饋表單 https://forms.gle/ehJmT3hqKtnzQQk17 ![qr.ioi.tw](https://hackmd.io/_uploads/Hyn6d7iVT.png)
{"description":"2023/11/22主講:劉正宗 老師","slideOptions":"{\"parallaxBackgroundImage\":\"\",\"backgroundTransition\":\"none\",\"transition\":\"slide\",\"transitionSpeed\":\"slow\",\"controlsBackArrows\":\"faded\",\"spotlight\":{\"enabled\":false}}","showTags":"true","title":"第 4 次社課講義","contributors":"[{\"id\":\"a5e01884-520b-4df5-8e23-bfcc32fb4697\",\"add\":18293,\"del\":7535},{\"id\":\"133c1d63-1697-43cd-a9d9-860f755172d1\",\"add\":32,\"del\":4}]"}
    601 views
   owned this note