# 第三次社課 - 小組競賽賽後題解
- 大家要繼續挑戰小組競賽題,你會看到兩個閒(ㄉ一ㄢˋ)閒(ㄉ一ㄢˋ)的教學已經破臺了
||其實是他們想寫水題炸魚||
## 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,此時剩下的線段長度就是最大公因數

:::
:::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: `資研`