---
# System prepended metadata

title: 第三次社課 - 小組競賽賽後題解
tags: [資研]

---

# 第三次社課 - 小組競賽賽後題解
- 大家要繼續挑戰小組競賽題，你會看到兩個閒(ㄉ一ㄢˋ)閒(ㄉ一ㄢˋ)的教學已經破臺了
||其實是他們想寫水題炸魚||
## 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: `資研`