# 第三次社課 - 小組競賽賽後題解 - 大家要繼續挑戰小組競賽題,你會看到兩個閒(ㄉ一ㄢˋ)閒(ㄉ一ㄢˋ)的教學已經破臺了 ||其實是他們想寫水題炸魚|| ## 100分題 ### 夢開始的地方: Hello HGISC! ###### tags: 基本輸入輸出 :::spoiler 程式碼 - C++ ```cpp= #include <iostream> using namespace std; int main(){ cout << "Hello HGISC!" << endl; } ``` - Python ```py= print("Hello HGISC!") ``` ::: ### 蝸牛老師的點名單 ###### tags: while(cin) :::spoiler 想法 - 題目會輸入1~30次名字,**次數不一定** -> 使用while(cin),有輸入就繼續跑,不用管未知的次數 ::: :::spoiler 程式碼 ```cpp= #include <iostream> using namespace std; int main() { string name; while(cin >> name){ cout << name << '\n'; } } ``` ::: ### 新手訓練 ~ for + if ###### tags: if-else、for :::spoiler 想法 - 看到2147483647這個數字代表你需要開long long int <-很多人都卡在這qwq ::: ::: spoiler 程式碼 ```cpp= #include<iostream> using namespace std; int main(){ long long int n, a, b, c; cin >> n; for(int i = 1 ; i <= n ; i++){ cin >> a >> b >> c; if(a == 1){ cout << b + c << endl; } else if(a == 2){ cout << b - c << endl; } else if(a == 3){ cout << b * c << endl; } else if(a == 4){ cout << b / c << endl; } } } ``` ::: ### 最大公因數 ###### tags: 輾轉相除法 :::spoiler 想法 - 找最大公因數的方法: 質因數分解法(耗時)、輾轉相除法 - 輾轉相除法(又稱歐幾里得算法,聯迎有上課的應該知道) - 持續從大數中減去小數,直到其中一段的長度為0,此時剩下的線段長度就是最大公因數 ![](https://i.imgur.com/9TY3gTw.gif) ::: :::spoiler 程式碼 ```cpp= #include <iostream> using namespace std; int main(){ int a, b; cin >> a >> b; while(b != 0){ int tmp = b; b = a % b; a = tmp; } cout << a; } ``` ::: ## 150分題 ### 罰時是什麼?可以吃嗎? ###### tags: 觀察、for、字串判斷 - 這是某教學因為想在zj測驗拿第一名所以去研究罰時規則的真人真事(*´艸`*) :::spoiler 想法 - 由圖可知罰時公式為: **AC送出時間加總+其他結果的次數*20** ::: :::spoiler 程式碼 ```cpp= #include <iostream> using namespace std; int main() { int n, min, ans = 0, wrong = 0; string result; cin >> n; for(int i = 0 ; i < n ; i += 1){ cin >> min >> result; if(result == "AC") ans += min; else wrong += 1; } cout << ans + wrong * 20; } ``` ::: ### 兔子跳躍 ###### tags: 窮舉 :::spoiler 想法 - d(距離)減掉n(可跳距離1)的倍數之後確認m(可跳距離2)是否可整除它 - 防止減到變負數 -> i <= d / n ::: :::spoiler 程式碼 ```cpp= #include <iostream> using namespace std; int main() { int n, m, d; cin >> n >> m >> d; bool ans = false; for(int i = 0 ; i <= d / n ; ++i){ int tmp = d - n * i; if(tmp >= 0 && tmp % m == 0){ ans = true; break; } } if(ans) cout << "YES\n"; else cout << "NO\n"; } ``` ::: ## 200分題 ### 基礎代謝率 ###### tags: setprecision、小數運算 :::spoiler 想法 - 難點在於四捨五入至小數點後兩位,其他就帶入題目給的公式 - 可使用的方法: 1. printf("**%.2f**; ", ans) 詳細語法可自行了解 2. iomanip裡的setprecision() 參見以下範例程式碼 ::: :::spoiler 程式碼 ```cpp= #include <iostream> #include <iomanip> using namespace std; int main() { int n, gender; double age, hgt, wgt; cin >> n; for(int i = 0 ; i < n ; i += 1){ cin >> gender >> age >> hgt >> wgt; if(gender) cout << fixed << setprecision(2) << (13.7*wgt)+(5.0*hgt)-(6.8*age)+66 << '\n'; else cout << fixed << setprecision(2) << (9.6*wgt)+(1.8*hgt)-(4.7*age)+655 << '\n'; } } ``` ::: ### 時間差計算 ###### tags: if-else、運算 :::spoiler 想法 - 全部換算成秒後再相減 - 依照不同情況做對應的輸出(此題麻煩、耗時之處) ::: :::spoiler 程式碼 ```cpp= #include <iostream> using namespace std; int main() { int h1, m1, s1, h2, m2, s2, total1, total2, ha, ma, sa; char c = ':'; cin >> h1 >> c >> m1 >> c >> s1; cin >> h2 >> c >>m2 >> c >> s2; total1 = h1 * 3600 + m1 * 60 + s1; total2 = h2 * 3600 + m2 * 60 + s2; total2 -= total1; if(total2 >= 0){ ha= total2 / 3600; total2 -= ha * 3600; ma = total2 / 60; total2 -= ma * 60; if(ha<10){ cout << 0 << ha << c; } else{ cout << ha << c; } if(ma<10){ cout << 0 << ma << c; } else{ cout << ma << c; } if(total2 < 10){ cout << 0 << total2; } else{ cout << total2; } } else{ total2 = 24 * 3600 + total2; ha = total2 / 3600; total2 -= ha * 3600; ma = total2 / 60; total2 -= ma * 60; if(ha < 10){ cout << 0 << ha << c; } else{ cout << ha << c; } if(ma < 10){ cout << 0 << ma << c; } else{ cout << ma << c; } if(total2 < 10){ cout << 0 << total2; } else{ cout << total2; } } } ``` ::: #### 如果覺得上面程式碼好長好可怕(ノД\`)的話! :::spoiler 一題多解 另一個電電神的程式碼(・ω´・ ) ```cpp= #include <iostream> using namespace std; int main(){ int h1, m1, s1, h2, m2, s2, ansh, ansm, anss; char c; cin >> h1 >> c >> m1 >> c >> s1 >> h2 >> c >> m2 >> c >> s2; if(s1 <= s2) anss = s2 - s1; else{ m2 -= 1; anss = (s2+60) - s1; } if(m1 <= m2) ansm = m2 - m1; else{ h2 -= 1; ansm = (m2+60) - m1; } if(h1 <= h2) ansh = h2 - h1; else{ ansh = (h2+24) - h1; } printf("%02d:%02d:%02d\n", ansh, ansm, anss); } ``` ::: #### 如果想被電的話! :::spoiler wym電神的函式+字串處理解 ```cpp= #include <bits/stdc++.h> using namespace std; string str(int x){ string ans; ans += ((x/10) + '0'); ans += ((x%10) + '0'); return ans; } string to(int x){ string ans; ans += str(x/3600); x%=3600; ans += ':'; ans += str(x/60); x%=60; ans += ':'; ans += str(x); return ans; } int main(){ string s1, s2; cin >> s1 >> s2; int a = stoi(s1.substr(0, 2))*3600 + stoi(s1.substr(3, 2))*60 + stoi(s1.substr(6, 2)); int b = stoi(s2.substr(0, 2))*3600 + stoi(s2.substr(3, 2))*60 + stoi(s2.substr(6, 2)); int sum = 24*3600; if(a <= b) cout << to(b-a) << "\n"; else{ cout << to(sum-a+b) << "\n"; } } ``` ::: ## 教學組給各位的建議(?) ### coding style - 巡堂過程中de大家的bug時,時常會看到相關的問題,間接導致debug不順(?) 1. 縮排不統一/錯誤 ```cpp int main() { int a,b; while(cin>>a>> b) while(a !=0 && b!=0) (a>b)? a=a%b :b=b%a; cout<<(a==0 ? b:a)<<endl; } ``` 2. 名稱重複使用(、誤解?) ```cpp int main(){ int N; int a; int b; int c; long long int a,b,c; int result; if (a==1) result=b+c; else if (a==2) result=b-c; else if (a==3) result=b*c; else if (a==4) result=b/a; } ``` - 雖然C++沒有縮排的話不像Python那樣嚴重到跑不起來(py會直接報錯) 但容易造成大家debug困難(像是少幾個大括號之類的問題) - 希望大家可以過目一下:[2022資芽竹區投影片](https://docs.google.com/presentation/d/1FJ0ddbDvuP01fRGjepT4aYvp8RYcPRMI/edit#slide=id.p2) [2022資芽北區投影片](https://docs.google.com/presentation/d/1tkZqmnl1zFmw2GXNspPdD2NVMzrO7bbyjy2ictkUT_Y/edit?usp=sharing) ||彩蛋: 仔細看題解的程式碼會發現for迴圈的更新有三種寫法|| ### 評測結果介紹 by wym | 結果 | 說明 | | -------- | -------- | | AC | 正確 | | NA | 阿就有錯啊,原因不一定,要點進去看 | | WA | 答案錯誤 | | TLE | 太慢 | | CE | 編譯錯誤aka zerojudge無法執行你的程式 | | RE | 等教完陣列再說 | - 也可以看Zerojudge首頁左側 ### 其他 - 善用google與各式資源 - 平常沒事可以練練題(不限於社課的)、去嘗試各種比賽||~~、成為教學明日之星(?)~~|| - 還是那句有問題隨時提出,我們看到都會盡快回覆der,不要放棄r qwq ||Never gonna give you up|| ###### tags: `資研`