---
# System prepended metadata

title: C++ 基礎語法練習題：Unit-7 function 函數、內建函數 vs. 自訂函數、全域變數 vs. 區域變數
tags: [演算法, C++, APCS, Python]

---

# C++ 基礎語法練習題：Unit-7 function 函數、內建函數 vs. 自訂函數、全域變數 vs. 區域變數

講義不是我寫的，原文連結為 [Yui Huang 演算法學習筆記：C++ 基礎語法](https://yuihuang.com/syntax/)
我只是將自己寫的練習題程式碼記錄下來。
最後更新日期：2024年11月12日


## [ZeroJudge: d039. 11044 - Searching for Nessy](https://zerojudge.tw/ShowProblem?problemid=d039)

### Python 程式碼

執行時間最久約為 27 ms，使用記憶體最多約為 3.3 MB，通過測試。
```python=
t = int(input())
for _ in range(t):
    n, m = map(int, input().split())
    print((n//3) * (m//3))
```

### C++ 程式碼

執行時間最久約為 3 ms，使用記憶體最多約為 348 kB，通過測試。
```cpp=
#include <iostream>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int t; cin >> t;
    for(int i=0; i<t; i++) {
        int n, m; cin >> n >> m;
        cout << (n/3) * (m/3) << "\n";
    }
    return 0;
}
```


## [ZeroJudge: a006. 一元二次方程式](https://zerojudge.tw/ShowProblem?problemid=a006)

### Python 程式碼

執行時間最久約為 21 ms，使用記憶體最多約為 3.3 MB，通過測試。
```python=
from math import sqrt

a, b, c = map(int, input().split())
D = b*b - 4*a*c
if D < 0: print("No real root")
elif D == 0: print(f"Two same roots x={-b//(2*a):d}")
else:
    x1 = (-b + int(sqrt(D)))//(2*a)
    x2 = (-b - int(sqrt(D)))//(2*a)
    print(f"Two different roots x1={x1:d} , x2={x2:d}")
```

### C++ 程式碼

執行時間最久約為 2 ms，使用記憶體最多約為 328 kB，通過測試。
```cpp=
#include <iostream>
#include <cmath>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int a, b, c; cin >> a >> b >> c;
    int D = b*b - 4*a*c;
    if (D < 0) {
        cout << "No real root\n";
    } else if (D == 0) {
        int x = -b/(2*a);
        cout << "Two same roots x=" << x << "\n";
    } else {
        int x1 = (-b + int(sqrt(D)))/(2*a);
        int x2 = (-b - int(sqrt(D)))/(2*a);
        cout << "Two different roots x1=" << x1 << " , x2=" << x2 << "\n";
    }
    return 0;
}
```


## [ZeroJudge: d255. 11417 - GCD](https://zerojudge.tw/ShowProblem?problemid=d255)

### Python 程式碼

單純的寫法，理論上會比較慢，但因為測資範圍不大，實際測試時反而比下一個寫法快一點。執行時間最久約為 4.2 s，使用記憶體最多約為 3.3 MB，通過測試。
```python=
from math import gcd

while True:
    N = int(input())  # 讀取 N
    if N == 0: break  # 如果 N == 0 中止迴圈
    G = 0  # 要計算的 G 值
    for i in range(1, N):  # 依序産生 1 ~ N-1
        for j in range(i+1, N+1):  # 依序産生 i+1 ~ N 
            G += gcd(i, j)  # 更新 G 值
    print(G)  # 印出 G
```

寫法2，先將 N = 1 ~ 501 對應的 gcd 值都算出來儲存到表格中，計算 G 值時直接從表格讀取資料。執行時間最久約為 4.1 s，使用記憶體最多約為 23.8 MB，通過測試。
```python=
from math import gcd

table = dict()  # 儲存 gcd(i, j)，以數組 (i, j) 為 key
for i in range(1, 500):
    for j in range(i+1, 501):
        table[i, j] = gcd(i, j)

while True:
    N = int(input())  # 讀取 N
    if N == 0: break  # 如果 N == 0 中止迴圈
    G = 0  # 要計算的 G 值
    for i in range(1, N):  # 依序産生 1 ~ N-1
        for j in range(i+1, N+1):  # 依序産生 i+1 ~ N
            G += table[i, j]  # 更新 G 值
    print(G)  # 印出 G
```

寫法3，先將 N = 1 ~ 501 對應的 gcd 值都算出來儲存到二維串列的表格中，計算 G 值時直接從表格讀取資料。執行時間最久約為 3 s，使用記憶體最多約為 5.3 MB，通過測試。
```python=
from math import gcd

table = [[0]*501 for _ in range(500)]
for i in range(1, 500):
    for j in range(i+1, 501):
        table[i][j] = gcd(i, j)

while True:
    N = int(input())  # 讀取 N
    if N == 0: break  # 如果 N == 0 中止迴圈
    G = 0  # 要計算的 G 值
    for i in range(1, N):  # 依序産生 1 ~ N-1
        for j in range(i+1, N+1):  # 依序産生 i+1 ~ N 
            G += table[i][j]  # 更新 G 值
    print(G)  # 印出 G
```


### C++ 程式碼

寫法1，執行時間最久約為 0.3 s，使用記憶體最多約為 320 kB，通過測試。
```cpp=
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    while(true) {
        int N; cin >> N;  // 讀取 N
        if (N == 0) break;  // 如果 N == 0 中止迴圈
        int G = 0;  // 要計算的 G 值
        for(int i=1; i<N; i++)  // 依序産生 1 ~ N-1
            for(int j=i+1; j<=N; j++)  // 依序産生 i+1 ~ N
                G += __gcd(i, j);  // 更新 G 值

        cout << G << "\n";  // 印出 G
    }
    return 0;
}
```

寫法2，如果要用 pair 作為 key，只能使用 map，不能使用 unordered_map。執行時間最久約為 1 s，使用記憶體最多約為 7.9 MB，通過測試。
```cpp=
#include <iostream>
#include <map>
#include <utility>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    map<pair<int, int>, int> table;  // 儲存已經計算過的 gcd(i, j)，以 pair (i, j) 為 key
    for(int i=1; i<500; i++)
        for(int j=i+1; j<501; j++)
            table[make_pair(i, j)] = __gcd(i, j);
    
    while(true) {
        int N; cin >> N;  // 讀取 N
        if (N == 0) break;  // 如果 N == 0 中止迴圈
        int G = 0;  // 要計算的 G 值
        for(int i=1; i<N; i++)  // 依序産生 1 ~ N-1
            for(int j=i+1; j<=N; j++)  // 依序産生 i+1 ~ N
                G += table[make_pair(i, j)];  // 更新 G 值

        cout << G << "\n";  // 印出 G
    }
    return 0;
}
```

寫法3，先將 N = 1 ~ 501 對應的 gcd 值都算出來儲存到二維陣列的表格中，計算 G 值時直接從表格讀取資料。執行時間最久約為 11 ms，使用記憶體最多約為 1.3 MB，通過測試。
```cpp=
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int table[500][501] = {0};  // 儲存已經計算過的 gcd(i, j)
    for(int i=1; i<500; i++)
        for(int j=i+1; j<501; j++)
            table[i][j] = __gcd(i, j);
    
    while(true) {
        int N; cin >> N;  // 讀取 N
        if (N == 0) break;  // 如果 N == 0 中止迴圈
        int G = 0;  // 要計算的 G 值
        for(int i=1; i<N; i++)  // 依序産生 1 ~ N-1
            for(int j=i+1; j<=N; j++)  // 依序産生 i+1 ~ N
                G += table[i][j];  // 更新 G 值

        cout << G << "\n";  // 印出 G
    }
    return 0;
}
```

---

###### tags:`演算法`、`APCS`、`Python`、`C++`