---
# System prepended metadata

title: GCD(UVA11417)
tags: [CPE一顆星必考題]

---

# GCD(UVA11417)
## [程式繳交區](https://hackmd.io/@Renektonn/S18g8y6uke/edit)
## 題目
[點我](https://onlinejudge.org/external/114/11417.pdf)

## 解題網站
[UVA](https://onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=2412)
[ZJ](https://zerojudge.tw/ShowProblem?problemid=d255)

## 演算法
```
1. 輸入n，若為0，則停止
2. G=0;
for(i=1;i<N;i++) {
    for(j=i+1;j<=N;j++) {
        G+=GCD(i,j);
    }
}
3. 輸出G
```

## 程式碼
```cpp=
#include <bits/stdc++.h>
using namespace std;
int gcd (int a, int b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

int main() {
    int n;
    while (cin >> n) {
        if (n == 0) break;
        int g = 0;
        for (int i = 1; i < n; i++) {
            for (int j = i + 1; j <= n; j++) {
                g += gcd(i, j);
            }
        }
        cout << g << endl;
    }

    return 0;
}
```

## 時間複雜度
$O(tn^2\log(n))$
$n=500, t=100$
$100\times250000\times 9=2.25\times10^8$
我覺得勉強能過

## 更好的演算法
使用動態規劃
```
1. 定義子問題：g(i)代表當n為i，G的值
2. 遞迴關係式：
g(n) = 1, n = 2
g(n) = g(n - 1) + gcd(j, i), j = [1, i - 1]
3. 計算順序：bottom-up，由小到大即可
4. 答案在g[n]
```
```
1. 使用動態規劃建表
2. 輸入n，若為0，則停止
3. 輸出g(n)
```

## 程式碼
```cpp=
#include <bits/stdc++.h>
using namespace std;
int gcd (int a, int b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

int main() {
    int g[501] = {};
    g[2] = 1;
    for (int i = 3; i <= 500; i++) {
        int sum = g[i - 1];
        for (int j = 1; j < i; j++) {
            sum += gcd(j, i);
        }
        g[i] = sum;
    }
    int n;
    while (cin >> n) {
        if (n == 0) break;
        cout << g[n] << endl;
    }
    return 0;
}
```

## 時間複雜度
$O(max(n^2, t))$
$n=500, t=100$
計算量為$250000=2.5\times10^5$