# C++ 基礎語法練習題:Unit-11 STL 標準模板庫
講義不是我寫的,原文連結為 [Yui Huang 演算法學習筆記:C++ 基礎語法](https://yuihuang.com/syntax/)
我只是將自己寫的練習題程式碼記錄下來。
最後更新日期:2024年11月17日
## [ZeroJudge: e529. 00482 - Permutation Arrays](https://zerojudge.tw/ShowProblem?problemid=e529)
### Python 程式碼
因為輸出時資料格式要按照輸入資料格式,用字串儲存資料比較方便。執行時間最久約為 19 ms,使用記憶體最多約為 3.3 MB,通過測試。
```python=
T = int(input())
for _ in range(T):
_ = input()
idx = list(map(int, input().split()))
xs = list(input().split())
arr = sorted([(i, x) for i, x in zip(idx, xs)])
for a in arr: print(a[1])
print()
```
### C++ 程式碼
執行時間最久約為 2 ms,使用記憶體最多約為 352 kB,通過測試。
```cpp=
#include <iostream>
#include <vector>
#include <sstream>
#include <string>
#include <utility>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int T; cin >> T; cin.ignore(); // 最後要用 cin.ignore() 跳過 \n
string s; stringstream ss; // 暫存資料用的字串 s,儲存空格分隔資料的 ss
for(int t=0; t<T; t++) { // 執行 T 次
getline(cin, s); // 讀取空行
vector<int> idx; // 資料索引值
vector<string> xs; // 資料字串
getline(cin, s); ss.clear(); ss << s; // 讀行一行資料存入 s,清空 ss,再將 s 存入 ss
while(ss >> s) idx.push_back(stoi(s)); // 由 ss 讀取資料、轉成 int 再放入 idx,直到 ss 沒有資料為止
getline(cin, s); ss.clear(); ss << s; // 讀行一行資料存入 s,清空 ss,再將 s 存入 ss
while(ss >> s) xs.push_back(s); // 由 ss 讀取資料放入 ixs,直到 ss 沒有資料為止
vector<pair<int, string>> arr; // 陣列,資料為 (i, x)
for(int i=0; i<(int)idx.size(); i++) arr.push_back(make_pair(idx[i], xs[i])); // 依序由 idx 及 xs 讀取資料存入 arr
sort(arr.begin(), arr.end()); // 依照 i 由小到大排序
for(auto a : arr) cout << a.second << "\n"; // 依序由 arr 讀取資料 a,印出 a.second
cout << "\n"; // 換行
}
return 0;
}
```
## [ZeroJudge: e155. 10935 - Throwing cards away I](https://zerojudge.tw/ShowProblem?problemid=e155)
### Python 程式碼
寫法1,使用 list 儲存卡片資料,理論上這樣寫並不好,因為 pop(0) 時間複雜度是 $O(n)$,效率不好,不過此題測資不大,這樣寫還是能通過測試。執行時間最久約為 18 ms,使用記憶體最多約為 3.3 MB,通過測試。
```python=
while True:
n = int(input()) # 卡片數量
if n == 0: break # 如果是 0 中止迴圈
print("Discarded cards: ", end="")
deck = list(range(1, n+1)) # 卡片串列
dis = [] # 丢棄的卡片
while len(deck) > 1: # 如果卡片數量大於 1 繼續執行
dis.append(deck.pop(0)) # 移除最前面的卡片再加到 dis
deck.append(deck.pop(0)) # 移除最前面的卡片再加到最後面
print(*dis, sep=", ") # 印出丢棄的卡片,以 ", " 分隔
print(f"Remaining card: {deck[0]:d}")
```
寫法2,使用 collections.deque 儲存卡片資料,執行速度跟 list 差不多,執行時間最久約為 21 ms,使用記憶體最多約為 3.6 MB,通過測試。
```python=
from collections import deque
while True:
n = int(input()) # 卡片數量
if n == 0: break # 如果是 0 中止迴圈
print("Discarded cards: ", end="")
deck = deque(range(1, n+1)) # 卡片雙向佇列
dis = [] # 丢棄的卡片
while len(deck) > 1: # 如果卡片數量大於 1 繼續執行
dis.append(deck.popleft()) # 移除最前面的卡片再加到 dis
deck.append(deck.popleft()) # 移除最前面的卡片再加到最後面
print(*dis, sep=", ") # 印出丢棄的卡片,以 ", " 分隔
print(f"Remaining card: {deck[0]:d}")
```
### C++ 程式碼
寫法1,使用 vector 儲存卡片資料,執行時間最久約為 2 ms,使用記憶體最多約為 324 kB,通過測試。
```cpp=
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
while(true) {
int n; cin >> n; // 卡片數量
if (n == 0) break; // 如果是 0 中止迴圈
cout << "Discarded cards: ";
if (n == 1) { // 只有一張卡片的特例
cout << "\n" << "Remaining card: 1\n";
} else {
vector<int> deck, dis; // deck 卡片,dis 丢棄的卡片
for(int i=1; i<=n; i++) deck.push_back(i);
while(deck.size() > 1) { // 如果卡片數量大於 1 繼續執行
dis.push_back(deck[0]); // 最前面的卡片加到 dis
deck.erase(deck.begin()); // 移除最前面的卡片
deck.push_back(deck[0]); // 最前面的卡片加到最後面
deck.erase(deck.begin()); // 移除最前面的卡片
}
for(int i=0; i<n-1; i++) { // 印出丢棄的卡片,以 ", " 分隔,最後一張換行
cout << dis[i] << (i == n-2 ? "\n" : ", ");
}
cout << "Remaining card: " << deck[0] << "\n";
}
}
return 0;
}
```
寫法2,由寫法1修改而成,直接印出移除的卡片。執行時間最久約為 2 ms,使用記憶體最多約為 316 kB,通過測試。
```cpp=
#include <iostream>
#include <vector>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
while(true) {
int n; cin >> n; // 卡片數量
if (n == 0) break; // 如果是 0 中止迴圈
cout << "Discarded cards: ";
if (n == 1) { // 只有一張卡片的特例
cout << "\n" << "Remaining card: 1\n";
} else {
vector<int> deck; // 卡片
for(int i=1; i<=n; i++) deck.push_back(i);
while(deck.size() > 1) { // 如果卡片數量大於 1 繼續執行
cout << deck[0] << (deck.size() == 2 ? "\n" : ", ");; // 印出最前面的卡片,剩2張時換行,否則用 ", " 分隔
deck.erase(deck.begin()); // 移除最前面的卡片
deck.push_back(deck[0]); // 最前面的卡片加到最後面
deck.erase(deck.begin()); // 移除最前面的卡片
}
cout << "Remaining card: " << deck[0] << "\n";
}
}
return 0;
}
```
寫法3,由寫法2修改而成,但改用 deque 儲存卡片資料。執行時間最久約為 2 ms,使用記憶體最多約為 316 kB,通過測試。
```cpp=
#include <iostream>
#include <deque>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
while(true) {
int n; cin >> n; // 卡片數量
if (n == 0) break; // 如果是 0 中止迴圈
cout << "Discarded cards: ";
if (n == 1) { // 只有一張卡片的特例
cout << "\n" << "Remaining card: 1\n";
} else {
deque<int> deck; // 卡片
for(int i=1; i<=n; i++) deck.push_back(i);
while(deck.size() > 1) { // 如果卡片數量大於 1 繼續執行
cout << deck.front() << (deck.size() == 2 ? "\n" : ", ");; // 印出最前面的卡片,剩2張時換行,否則用 ", " 分隔
deck.pop_front(); // 移除最前面的卡片
deck.push_back(deck.front()); // 最前面的卡片加到最後面
deck.pop_front(); // 移除最前面的卡片
}
cout << "Remaining card: " << deck.front() << "\n";
}
}
return 0;
}
```
## [ZeroJudge: e564. 00540 - Team Queue](https://zerojudge.tw/ShowProblem?problemid=e564)
### Python 程式碼
執行時間最久約為 25 ms,使用記憶體最多約為 4 MB,通過測試。
```python=
ca = 0 # 測資編號
while True:
ca += 1 # 測資編號加 1
t = int(input()) # 團隊數量
if t == 0: break # 如果是 0 中止迴圈
print(f"Scenario #{ca:d}") # 印出 Scenario #ca
people = dict() # 每個人所屬的組別,{編號:組別}
que = [] # 二維串列,同團隊成員放在同一個一維串列中
last = [-1]*t # 每一組於 que 之中的索引值,如果不在 que 之中為 -1
for i in range(t): # 讀取 t 行
data = list(input().split()) # 團隊成員編號
for d in data[1:]: # 依序讀取團隊成員編號
people[d] = i # 以成員編號為 key,存入團隊編號 i
# end of for loop
while True: # 讀取指令
line = list(input().split()) # 用空格分隔存入串列
if line[0] == "STOP": break # 如果是 STOP 中止迴圈
elif line[0] == "ENQUEUE": # 如果是 ENQUEUE
p = line[1] # 排入的成員編號 p
idx = last[people[p]] # p 所屬團隊於 que 中的索引值 idx
if idx == -1 or len(que) == 0: # 如果 idx 是 -1 或是 que 沒有資料
que.append([p]) # 將 p 放入一維串列,接在 que 最後面
last[people[p]] = len(que)-1 # p 所屬團隊於 que 中的索引值為 que 長度減 1
else: # 其它狀況
que[idx].append(p) # 於 que[idx] 加入 p
elif line[0] == "DEQUEUE": # 如果是 DEQUEUE
p = que[0].pop(0) # 從 que 開頭的一維串列中移除最前面一項項存入 p
print(p) # 印出 p
if len(que[0]) == 0: # 如果 que 開頭的一維串列是空的
que.pop(0) # 移除 que 開頭的一維串列
for i in range(t): # 更新 last
if i == people[p]: last[i] = -1 # p 所屬團隊於 que 中的索引值為 -1
elif last[i] != -1: last[i] -= 1 # 如果 last[i] 不是 -1 則減 1
# end of while loop
print() # 換行
```
### C++ 程式碼
執行時間最久約為 4 ms,使用記憶體最多約為 696 kB,通過測試。
```cpp=
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int ca = 0; // 測資編號
while(true) {
ca++; // 測資編號加 1
int t; cin >> t; // 團隊數量
if (t == 0) break; // 如果是 0 中止迴圈
cout << "Scenario #" << ca << "\n"; // 印出 Scenario #ca
unordered_map<string, int> people; // 每個人所屬的組別,{編號:組別}
vector<vector<string>> que; // 二維陣列,同團隊成員放在同一個一維陣列中
vector<int> last (t, -1); // 每一組於 que 之中的索引值,如果不在 que 之中為 -1
for(int i=0; i<t; i++) { // 讀取 t 行
int n; cin >> n; // 團隊成員人數
string d; // 團隊成員編號
for(int j=0; j<n; j++) { // 依序讀取團隊成員編號
cin >> d; people[d] = i; // 以成員編號為 key,存入團隊編號 i
}
}
while(true) {
string s; cin >> s; // 讀取指令
if (s == "STOP") break; // 如果是 STOP 中止迴圈
else if (s == "ENQUEUE") { // 如果是 ENQUEUE
string p; cin >> p; // 排入的成員編號 p
int idx = last[people[p]]; // p 所屬團隊於 que 中的索引值 idx
if (idx == -1 || que.empty()) { // 如果 idx 是 -1 或是 que 沒有資料
que.push_back(vector<string> (1, p)); // 將 p 放入一維串列,接在 que 最後面
last[people[p]] = (int)que.size()-1; // p 所屬團隊於 que 中的索引值為 que 長度減 1
} else { // 其它狀況
que[idx].push_back(p); // 於 que[idx] 加入 p
}
} else if (s == "DEQUEUE") { // 如果是 DEQUEUE
string p = que[0][0]; // 從 que 開頭的一維串列中移除最前面一項項存入 p
que[0].erase(que[0].begin());
cout << p << "\n"; // 印出 p
if (que[0].empty()) { // 如果 que 開頭的一維串列是空的
que.erase(que.begin()); // 移除 que 開頭的一維串列
for(int i=0; i<t; i++) { // 更新 last
if (i == people[p]) last[i] = -1; // p 所屬團隊於 que 中的索引值為 -1
else if (last[i] != -1) last[i]--; // 如果 last[i] 不是 -1 則減 1
}
}
}
}
cout << "\n"; // 換行
}
return 0;
}
```
## [ZeroJudge: b838. 104北二2.括號問題](https://zerojudge.tw/ShowProblem?problemid=b838)
### Python 程式碼
執行時間最久約為 19 ms,使用記憶體最多約為 3.3 MB,通過測試。
```python=
t = int(input()) # 測資組數
for _ in range(t): # 執行 t 次
s = input().strip() # 測資字串,要用 strip() 刪除結尾的 \n
left = 0 # 左括號數量
cnt = 0 # 成對括號數量
flag = True # 是否成對
for c in s: # 依序由 s 讀取字元存入 c
if c == "(": # 如果是 (
left += 1 # 左括號數量加 1
else: # 如果是 )
if left >= 1: # 如果左括號數量大於等於1,可以成對
cnt += 1 # cnt 加 1
left -= 1 # left 減 1
else: # 否則不能成對
flag = False # 設定為 False
break # 中止迴圈
if flag and left == 0: # 如果 flag 為 True 且左括號都用完
print(cnt) # 印出 cnt
else: print(0) # 否則印出 0
```
### C++ 程式碼
執行時間最久約為 2 ms,使用記憶體最多約為 336 kB,通過測試。
```cpp=
#include <iostream>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int t; cin >> t; // 測資組數
for(int i=0; i<t; i++) { // 執行 t 次
string s; cin >> s; // 測資字串
int left = 0, cnt = 0; // left 左括號數量,cnt 成對括號數量
bool flag = true; // 是否成對
for(char c : s) { // 依序由 s 讀取字元存入 c
if (c == '(') { // 如果是 (
left++; // 左括號數量加 1
} else { // 如果是 )
if (left >= 1) { // 如果左括號數量大於等於1,可以成對
cnt++; // cnt 加 1
left--; // left 減 1
} else { // 否則不能成對
flag = false; // 設定為 False
break; // 中止迴圈
}
}
}
cout << (flag && left == 0 ? cnt : 0) << "\n"; // 如果 flag 為 True 且左括號都用完印出 cnt,否則印出 0
}
return 0;
}
```
## [ZeroJudge: c123. 00514 - Rails](https://zerojudge.tw/ShowProblem?problemid=c123)
### Python 程式碼
執行時間最久約為 0.2 s,使用記憶體最多約為 3.7 MB,通過測試。
```python=
while True:
n = int(input()) # 車廂數量
if n == 0: break # 如果是 0 中止迴圈
while True:
line = input() # 讀取一行資料
if line == "0": break # 如果是 "0" 中止迴圈
target = list(map(int, line.split())) # 目標排列方式
A = list(range(1, n+1)) # A 軌道上的列車
B = [] # B 軌道上的列車
S = [] # 車站軌道上的列車
now = 0 # 正在檢測的 target 索引值
while True:
if A and A[0] == target[now]: # 如果 A 有資料而且 A[0] 等於目標
B.append(A.pop(0)) # 移除 A 開頭資料加到 B 最後面
now += 1 # now 加 1
elif S and S[-1] == target[now]: # 如果 S 有資料而且 S[-1] 等於目標
B.append(S.pop()) # 移除 S 最後一項加到 B 最後面
now += 1 # now 加 1
elif A: # 如果 A 有資料
S.append(A.pop(0)) # 移除 A 開頭資料加到 S 最後面
else: break # 其它狀況,中止迴圈
print("Yes" if len(B) == n else "No") # 如果 B 的長度等於 n 印出 Yes
# end of while loop
print() # 換行
```
使用 collections.deque,執行時間最久約為 0.2 s,使用記憶體最多約為 4.2 MB,通過測試。
```python=
from collections import deque
while True:
n = int(input()) # 車廂數量
if n == 0: break # 如果是 0 中止迴圈
while True:
line = input() # 讀取一行資料
if line == "0": break # 如果是 "0" 中止迴圈
target = tuple(map(int, line.split())) # 目標排列方式
A = deque(range(1, n+1)) # A 軌道上的列車
B = deque() # B 軌道上的列車
S = deque() # 車站軌道上的列車
now = 0 # 正在檢測的 target 索引值
while True:
if A and A[0] == target[now]: # 如果 A 有資料而且 A[0] 等於目標
B.append(A.popleft()) # 移除 A 開頭資料加到 B 最後面
now += 1 # now 加 1
elif S and S[-1] == target[now]: # 如果 S 有資料而且 S[-1] 等於目標
B.append(S.pop()) # 移除 S 最後一項加到 B 最後面
now += 1 # now 加 1
elif A: # 如果 A 有資料
S.append(A.popleft()) # 移除 A 開頭資料加到 S 最後面
else: break # 其它狀況,中止迴圈
print("Yes" if len(B) == n else "No") # 如果 B 的長度等於 n 印出 Yes
# end of while loop
print() # 換行
```
### C++ 程式碼
執行時間最久約為 20 ms,使用記憶體最多約為 360 kB,通過測試。
```cpp=
#include <iostream>
#include <deque>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
while(true) {
int n; cin >> n; // 車廂數量
if (n == 0) break; // 如果是 0 中止迴圈
while(true) {
int t; cin >> t; // 讀取一個數字
if (t == 0) break; // 如果是 0 中止迴圈
deque<int> target; target.push_back(t); // 目標排列方式
for(int i=1; i<n; i++) {
cin >> t;
target.push_back(t);
}
deque<int> A, B, S; // A 軌道、B 軌道、車站軌道上的列車
for(int i=1; i<=n; i++) A.push_back(i);
while(true) {
if (!A.empty() && A.front() == target.front()) { // 如果 A 有資料而且 A.front() 等於目標
B.push_back(A.front()); // A 開頭資料加到 B 最後面
A.pop_front(); // 移除 A 開頭資料
target.pop_front(); // 移除 target 開頭資料
} else if (!S.empty() && S.back() == target.front()) { // 如果 S 有資料而且 S.back() 等於目標
B.push_back(S.back()); // S 最後一項加到 B 最後面
S.pop_back(); // 移除 S 最後一項
target.pop_front(); // 移除 target 開頭資料
} else if (!A.empty()) { // 如果 A 有資料
S.push_back(A.front()); // A 開頭資料加到 S 最後面
A.pop_front(); // 移除 A 開頭資料
} else {
break; // 其它狀況,中止迴圈
}
}
cout << ((int)B.size() == n ? "Yes" : "No") << "\n"; // 如果 B 的長度等於 n 印出 Yes
}
cout << "\n"; // 換行
}
return 0;
}
```
## [ZeroJudge: f640. 函數運算式求值](https://zerojudge.tw/ShowProblem?problemid=f640)
### Python 程式碼
使用 list 作為堆疊儲存數值,執行時間最久約為 41 ms,使用記憶體最多約為 3.3 MB,通過測試。另外有[遞迴寫法](https://hackmd.io/@yizhewang/B1w_uVGzke#ZeroJudge-f640-%E5%87%BD%E6%95%B8%E9%81%8B%E7%AE%97%E5%BC%8F%E6%B1%82%E5%80%BC)。
```python=
def f(x):
return 2*x - 3
def g(x, y):
return 2*x + y - 7
def h(x, y, z):
return 3*x - 2*y + z
s = list(input().split())
nums = []
while s:
c = s.pop()
if c == 'f':
x = nums.pop()
nums.append(f(x))
elif c == 'g':
x = nums.pop()
y = nums.pop()
nums.append(g(x, y))
elif c == 'h':
x = nums.pop()
y = nums.pop()
z = nums.pop()
nums.append(h(x, y, z))
else: nums.append(int(c))
print(nums[0])
```
### C++ 程式碼
執行時間最久約為 2 ms,使用記憶體最多約為 360 kB,通過測試。
```cpp=
#include <iostream>
#include <stack>
#include <string>
using namespace std;
int f(int x) {
return 2*x - 3;
}
int g(int x, int y) {
return 2*x + y - 7;
}
int h(int x, int y, int z) {
return 3*x - 2*y + z;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
string s; stack<string> ss;
while(cin >> s) ss.push(s);
stack<int> nums;
while(!ss.empty()) {
s = ss.top(); ss.pop();
if (s == "f") {
int x = nums.top(); nums.pop();
nums.push(f(x));
} else if (s == "g") {
int x = nums.top(); nums.pop();
int y = nums.top(); nums.pop();
nums.push(g(x, y));
} else if (s == "h") {
int x = nums.top(); nums.pop();
int y = nums.top(); nums.pop();
int z = nums.top(); nums.pop();
nums.push(h(x, y, z));
} else {
nums.push(stoi(s));
}
}
cout << nums.top() << "\n";
return 0;
}
```
## [ZeroJudge: f607. 3. 切割費用](https://zerojudge.tw/ShowProblem?problemid=f607)
### Python 程式碼
執行時間最久約為 1.1 s,使用記憶體最多約為 34.3 MB,通過測試。
```python=
from bisect import bisect_left
n, L = map(int, input().split()) # 切割次數 n,長度 L
cost = 0 # 成本
points = [0, L] # 已切割點位置,先放入兩端
# 讀取 n 行資料,每行組成數組 (x, i),依照 i 由小到大排序
xi = sorted([tuple(map(int, input().split())) for _ in range(n)], key = lambda x : x[1])
for x, i in xi: # 依序讀取切割點 x、序號 i,但是 i 用不到
idx = bisect_left(points, x) # 用二分搜尋法找 x 於 points 中插入的位置
cost += points[idx] - points[idx-1] # 成本加上 x 兩側端點距離
points.insert(idx, x) # 於 idx 位置插入 x
print(cost) # 印出成本
```
### C++ 程式碼
本題的答案很大,在 $2^{31}$ 到 $2^{60}$ 之間,使用 int 會溢位,要使用 long long。執行時間最久約為 0.1 s,使用記憶體最多約為 6.9 MB,通過測試。
```cpp=
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
typedef long long LL;
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
LL n, L; cin >> n >> L; // 切割次數 n,長度 L
LL cost = 0; // 成本
vector<LL> points = {0, L}; // 已切割點位置,先放入兩端
/* 讀取 n 行資料,每行組成 pair (i, x),依照 i 由小到大排序 */
vector<pair<LL, LL>> xi (n, pair<LL, LL> ());
for(LL i=0; i<n; i++) cin >> xi[i].second >> xi[i].first;
sort(xi.begin(), xi.end());
for(auto p : xi) { // 依序讀取切割點
LL x = p.second; // 切割點位置 x
LL idx = lower_bound(points.begin(), points.end(), x) - points.begin(); // 用二分搜尋法找 x 於 points 中插入的位置
cost += points[idx] - points[idx-1]; // 成本加上 x 兩側端點距離
points.insert(idx + points.begin(), x); // 插入 x
}
cout << cost << "\n"; // 印出成本
return 0;
}
```
## [ZeroJudge: d123. 11063 - B2-Sequence](https://zerojudge.tw/ShowProblem?problemid=d123)
因為條件為 $b_i + b_j$ 皆不相等而且 $i \leq j$,要檢測 $i = j$ 的狀況。
### Python 程式碼
使用 set,執行時間最久約為 29 ms,使用記憶體最多約為 3.3 MB,通過測試。
```python=
import sys
ca = 0 # 第幾個測試的 case
for line in sys.stdin:
ca += 1 # ca 加 1
n = int(line)
arr = list(map(int, input().split()))
found = set() # 已被找到過的任意兩數加總
flag = True # 是否為 B2-Sequence
for i in range(n): # 依序産生 0 ~ n-1
if not flag: break # 如果已經確定不是 B2-Sequence,中止迴圈
for j in range(i, n): # 依序産生 i ~ n-1
isum = arr[i] + arr[j] # 計算任意兩數的加總
if isum in found: # 如果加總已被找到過
flag = False # 不是 B2-Sequence
break # 中止迴圈
else: found.add(isum) # isum 加入 found
print(f"Case #{ca:d}: It is ", end="")
print("a B2-Sequence.\n" if flag else "not a B2-Sequence.\n")
```
使用 collections.defaultdict,執行時間最久約為 33 ms,使用記憶體最多約為 3.7 MB,通過測試。
```python=
import sys
from collections import defaultdict
ca = 0 # 第幾個測試的 case
for line in sys.stdin:
ca += 1 # ca 加 1
n = int(line)
arr = list(map(int, input().split()))
found = defaultdict(bool) # 任意兩數加總是否有被找到過
flag = True # 是否為 B2-Sequence
for i in range(n): # 依序産生 0 ~ n-1
if not flag: break # 如果已經確定不是 B2-Sequence,中止迴圈
for j in range(i, n): # 依序産生 i ~ n-1
isum = arr[i] + arr[j] # 計算任意兩數的加總
if found[isum]: # 如果加總已被找到過
flag = False # 不是 B2-Sequence
break # 中止迴圈
else: found[isum] = True # 設定 isum 狀態為已找到
print(f"Case #{ca:d}: It is ", end="")
print("a B2-Sequence.\n" if flag else "not a B2-Sequence.\n")
```
### C++ 程式碼
使用 set,執行時間最久約為 4 ms,使用記憶體最多約為 324 kB,通過測試。
```cpp=
#include <iostream>
#include <set>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n, ca = 0; // # 第幾個測試的 case
while(cin >> n) {
ca++; // ca 加 1
int arr[n];
for(int i=0; i<n; i++) cin >> arr[i];
set<int> found; // 已被找到過的任意兩數加總
bool flag = true; // 是否為 B2-Sequence
for(int i=0; i<n; i++) { // 依序産生 0 ~ n-1
if (!flag) break; // 如果已經確定不是 B2-Sequence,中止迴圈
for(int j=i; j<n; j++) { // 依序産生 i ~ n-1
int isum = arr[i] + arr[j]; // 計算任意兩數的加總
if (found.count(isum) == 1) { // 如果加總已被找到過
flag = false; // 不是 B2-Sequence
break; // 中止迴圈
} else found.insert(isum); // isum 加入 found
}
}
cout << "Case #" << ca << ": It is ";
cout << (flag ? "a" : "not a") << " B2-Sequence.\n\n";
}
return 0;
}
```
使用 unordered_map,執行時間最久約為 4 ms,使用記憶體最多約為 364 kB,通過測試。
```cpp=
#include <iostream>
#include <unordered_map>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n, ca = 0; // # 第幾個測試的 case
while(cin >> n) {
ca++; // ca 加 1
int arr[n];
for(int i=0; i<n; i++) cin >> arr[i];
unordered_map<int, bool> found; // 已被找到過的任意兩數加總
bool flag = true; // 是否為 B2-Sequence
for(int i=0; i<n; i++) { // 依序産生 0 ~ n-1
if (!flag) break; // 如果已經確定不是 B2-Sequence,中止迴圈
for(int j=i; j<n; j++) { // 依序産生 i ~ n-1
int isum = arr[i] + arr[j]; // 計算任意兩數的加總
if (found[isum]) { // 如果加總已被找到過
flag = false; // 不是 B2-Sequence
break; // 中止迴圈
} else found[isum] = true; // found[isum] 設定為 true
}
}
cout << "Case #" << ca << ": It is ";
cout << (flag ? "a" : "not a") << " B2-Sequence.\n\n";
}
return 0;
}
```
## [ZeroJudge: d442. 10591 - Happy Number](https://zerojudge.tw/ShowProblem?problemid=d442)
### Python 程式碼
執行時間最久約為 0.8 s,使用記憶體最多約為 3.3 MB,通過測試。
```python=
def ssum(n): # 計算各位數字平方和
tot = 0
while n > 0:
d = n%10
tot += d*d
n //= 10
return tot
N = int(input()) # 測資數量
for i in range(1, N+1): # 執行 N 次
n = int(input()) # 要測試的數字
print(f"Case #{i:d}: {n:d} is ", end="") # 印出開頭
flag = False # 是否為 happy number
tested = set() # 已測試的數字
while True:
if n == 1: # 如果 n 等於 1
flag = True # 是 happy number
break # 中止迴圈
elif n in tested: # 如果 n 在 tested 之中,不是 happy number
break # 中止迴圈
else: # 其它狀況
tested.add(n) # 將 n 加入 tested
n = ssum(n) # 計算各位數字平方和,更新 n
print("a Happy number." if flag else "an Unhappy number.")
```
### C++ 程式碼
執行時間最久約為 59 ms,使用記憶體最多約為 348 kB,通過測試。
```cpp=
#include <iostream>
#include <set>
using namespace std;
int ssum(int n) { // 計算各位數字平方和
int tot = 0;
while(n > 0) {
int d = n%10;
tot += d*d;
n /= 10;
}
return tot;
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int N; cin >> N; // 測資數量
for(int i=1; i<=N; i++) { // 執行 N 次
int n; cin >> n; // 要測試的數字
cout << "Case #" << i << ": " << n << " is "; // 印出開頭
bool flag = false; // 是否為 happy number
set<int> tested; // 已測試的數字
while(true) {
if (n == 1) { // 如果 n 等於 1
flag = true; // 是 happy number
break; // 中止迴圈
} else if (tested.count(n) == 1) { // 如果 n 在 tested 之中,不是 happy number
break; // 中止迴圈
} else { // 其它狀況
tested.insert(n); // 將 n 加入 tested
n = ssum(n); // 計算各位數字平方和,更新 n
}
}
cout << (flag ? "a Happy number.\n" : "an Unhappy number.\n");
}
return 0;
}
```
## [ZeroJudge: a135. 12250 - Language Detection](https://zerojudge.tw/ShowProblem?problemid=a135)
### Python 程式碼
執行時間最久約為 19 ms,使用記憶體最多約為 3.3 MB,通過測試。
```python=
lan = {"HELLO": "ENGLISH",
"HOLA": "SPANISH",
"HALLO": "GERMAN",
"BONJOUR": "FRENCH",
"CIAO": "ITALIAN",
"ZDRAVSTVUJTE": "RUSSIAN"}
ca = 0
while True:
s = input()
if s == "#": break
ca += 1
print(f"Case {ca:d}: ", end="")
if s not in lan:
print("UNKNOWN")
else:
print(lan[s])
```
### C++ 程式碼
執行時間最久約為 2 ms,使用記憶體最多約為 356 kB,通過測試。
```cpp=
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
unordered_map<string, string> lan = {{"HELLO", "ENGLISH"},
{"HOLA", "SPANISH"},
{"HALLO", "GERMAN"},
{"BONJOUR", "FRENCH"},
{"CIAO", "ITALIAN"},
{"ZDRAVSTVUJTE", "RUSSIAN"}};
int ca = 0;
while(true) {
string s; cin >> s;
if (s == "#") break;
ca++;
cout << "Case " << ca << ": ";
if (lan[s] == "") cout << "UNKNOWN\n";
else cout << lan[s] << "\n";
}
return 0;
}
```
## [ZeroJudge: e641. 10260 - Soundex](https://zerojudge.tw/ShowProblem?problemid=e641)
**注意:相同發音編號的字母如果相連只輸出一次編號,即使字母之間有空格也視為相連。**
### Python 程式碼
因為 Python 可以用 in 判斷字元是否存在於字串之中,以下的寫法反而比用 dict 還要好懂。執行時間最久約為 17 ms,使用記憶體最多約為 3.3 MB,通過測試。
```python=
import sys
for line in sys.stdin:
pre = 0
for c in line:
if c in "BFPV" and pre != 1:
print("1", end="")
pre = 1
elif c in "CGJKQSXZ" and pre != 2:
print("2", end="")
pre = 2
elif c in "DT" and pre != 3:
print("3", end="")
pre = 3
elif c in "L" and pre != 4:
print("4", end="")
pre = 4
elif c in "MN" and pre != 5:
print("5", end="")
pre = 5
elif c in "R" and pre != 6:
print("6", end="")
pre = 6
elif c in "AEIOUHWY":
pre = 0
print()
```
由於 Python 的 dict 如果讀到不存在的 key 會回傳錯誤,必須使用 collections.defaultdict 才行。以下的程式碼第4到8行先建立每個字母對應的編碼,為了輸出時比較方便,編碼也採用字元格式;第9行再轉換成 defaultdict,預設格式為 str,如果輸入不存在的 key 值會回傳空字串。
```python=
import sys
from collections import defaultdict
table = {'A': '0', 'B': '1', 'C': '2', 'D': '3', 'E': '0', 'F': '1',
'G': '2', 'H': '0', 'I': '0', 'J': '2', 'K': '2', 'L': '4',
'M': '5', 'N': '5', 'O': '0', 'P': '1', 'Q': '2', 'R': '6',
'S': '2', 'T': '3', 'U': '0', 'V': '1', 'W': '0', 'X': '2',
'Y': '0', 'Z': '2'}
table = defaultdict(str, table)
for line in sys.stdin:
pre = '0'
for c in line:
if table[c] != pre:
if table[c] != '0': # 編碼不是 '0' 才需要輸出
print(table[c], end="")
pre = table[c]
print()
```
### C++ 程式碼
執行時間最久約為 2 ms,使用記憶體最多約為 328 kB,通過測試。
```cpp=
#include <iostream>
#include <string>
#include <map>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
map<char, char> table = {{'A', '0'}, {'B', '1'}, {'C', '2'}, {'D', '3'}, {'E', '0'}, {'F', '1'},
{'G', '2'}, {'H', '0'}, {'I', '0'}, {'J', '2'}, {'K', '2'}, {'L', '4'},
{'M', '5'}, {'N', '5'}, {'O', '0'}, {'P', '1'}, {'Q', '2'}, {'R', '6'},
{'S', '2'}, {'T', '3'}, {'U', '0'}, {'V', '1'}, {'W', '0'}, {'X', '2'},
{'Y', '0'}, {'Z', '2'}};
string line;
char pre = '0';
while(cin >> line) {
for(char c : line) {
if (table[c] != pre) {
if (table[c] != '0') cout << table[c];
pre = table[c];
}
}
cout << "\n";
}
return 0;
}
```
## [ZeroJudge: d267. 11577 - Letter Frequency](https://zerojudge.tw/ShowProblem?problemid=d267)
不使用 map 的寫法請參考[這個頁面](https://hackmd.io/@yizhewang/BJEvlKxf1x#ZeroJudge-d267-11577---Letter-Frequency)。
### Python 程式碼
以下是比較具有 Python 風格的寫法,執行時間最久約為 24 ms,使用記憶體最多約為 3.6 MB,通過測試。
```python=
import sys
from collections import Counter
n = int(input())
for _ in range(n):
s = (input()).lower() # 全部轉成小寫字母
cnt = Counter(s) # 計數器
imax = 0
ans = ""
for k, v in cnt.items(): # 讀取數量最多的字母
if k.isalpha():
if v > imax: ans = k; imax = v
elif v == imax: ans += k
print("".join(sorted(ans))) # 排序後接成字串再輸出
```
### C++ 程式碼
執行時間最久約為 3 ms,使用記憶體最多約為 352 kB,通過測試。
```cpp=
#include <iostream>
#include <string>
#include <map>
#include <cctype> // isalpha, tolower
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n; cin >> n; cin.ignore();
for(int i=0; i<n; i++) {
string s; getline(cin, s); // 讀取一行字串
map<char, int> cnt; // 計數器
for(char c : s) { // 依序由 s 讀取字元 c,如果 c 是字母,轉成小寫,數量加 1
if (isalpha(c)) cnt[tolower(c)]++;
}
int imax = 0; // 數量最大值
string ans = ""; // 儲存答案用的空字串
for(auto cn : cnt) { // 讀取數量最多的字母
if (cn.second > imax) {
ans = cn.first;
imax = cn.second;
} else if (cn.second == imax) {
ans += cn.first;
}
}
sort(ans.begin(), ans.end()); // 排序後再輸出
cout << ans << "\n";
}
return 0;
}
```
## [ZeroJudge: d221. 10954 - Add All](https://zerojudge.tw/ShowProblem?problemid=d221)
我另外寫的筆記〈[Python 及 C++ 優先佇列 (priority queue)](https://hackmd.io/@yizhewang/S1EBLEAvT)〉。
### Python 程式碼
Python 的 priority queue 名稱為 heapq,需要引入函式庫 heapq,而且是最小值放上面的最小堆積樹。執行時間最久約為 0.2 s,使用記憶體最多約為 4.6 MB,通過測試。
```python=
import heapq as hq
while True:
n = int(input())
if n == 0: break
pq = list(map(int, input().split())) # 讀取一行資料轉成 list
hq.heapify(pq) # 轉成 priority queue,最小值放在上面
cost = 0 # 成本
while len(pq) > 1: # 當 pq 長度大於 1 繼續執行
a = hq.heappop(pq) # 取出最小值 a
b = hq.heappop(pq) # 取出最小值 c
c = a+b # 相加的成本 c
cost += c # 更新 cost
hq.heappush(pq, c) # 將 c 放入 pq
print(cost) # 印出 cost
```
### C++ 程式碼
要使用 long long 才不會溢位,執行時間最久約為 23 ms,使用記憶體最多約為 464 kB,通過測試。
```cpp=
#include <iostream>
#include <queue>
#include <vector>
#include <string>
typedef long long LL;
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
while(true) {
int n; cin >> n;
if (n == 0) break;
priority_queue<LL, vector<LL>, greater<LL>> pq; // priority queue,最小值放在上面
for(int i=0; i<n; i++) {
LL m; cin >> m; pq.push(m);
}
LL cost = 0; // 成本
while(pq.size() > 1) { // 當 pq 長度大於 1 繼續執行
LL a = pq.top(); pq.pop(); // 取出最小值 a
LL b = pq.top(); pq.pop(); // 取出最小值 c
LL c = a+b; // 相加的成本 c
cost += c; // 更新 cost
pq.push(c); // 將 c 放入 pq
}
cout << cost << "\n"; // 印出 cost
}
return 0;
}
```
## [ZeroJudge: c875. 107北二2.裝置藝術](https://zerojudge.tw/ShowProblem?problemid=c875)
### Python 程式碼
第20筆測資,程式碼第5行遇到 MemoryError。
```python=
import heapq as hq
A, B, C = map(int, input().split()) # 飲料塔數量 A,一個飲料罐的高度 B,最大高度差 C
C = (C - C%B) // B # 改成對應的飲料罐數量,例如 B = 2, C = 5,修改成 C = 2
hs = list(map(int, input().split())) # 每個飲料塔原來的高度
hs = [h//B for h in hs] # 修改成原來的飲料罐數量
pq = [(h, i) for i, h in enumerate(hs)] # 組成 tuple
hq.heapify(pq) # 轉成 priority queue,依照高度由小到大排序
ans = 0 # 要移除的罐子數量
while pq:
h, i = hq.heappop(pq) # 取出目前最低的飲料塔高度 h、位置 i
if i != A-1 and hs[i+1] - h > C: # 跟右邊比較高度差,如果右邊較高則降低高度
num = (hs[i+1] - h - C) # 要移除的罐子數量
ans += num
hs[i+1] -= num
hq.heappush(pq, (hs[i+1], i+1))
if i != 0 and hs[i-1] - h > C: # 跟左邊比較高度差,如果左邊較高則降低高度
num = (hs[i-1] - h - C)
ans += num
hs[i-1] -= num
hq.heappush(pq, (hs[i-1], i-1))
# end of while loop
print(ans)
```
如果改成用自訂函式分割字串,第20筆測資變成在程式碼第16行遇到 MemoryError。
```python=
import heapq as hq
def stringStream(s, sep):
start = 0
for end in range(len(s)):
if s[end] in sep:
yield s[start:end]
start = end + 1
if start < len(s):
yield s[start:]
A, B, C = map(int, input().split()) # 飲料塔數量 A,一個飲料罐的高度 B,最大高度差 C
C = (C - C%B) // B # 改成對應的飲料罐數量,例如 B = 2, C = 5,修改成 C = 2
line = input() # 讀取一行資料
hs = [int(h)//B for h in stringStream(line, " \n")] # 每個飲料塔原來的飲料罐數量
pq = [(h, i) for i, h in enumerate(hs)] # 組成 tuple
hq.heapify(pq) # 轉成 priority queue,依照高度由小到大排序
ans = 0 # 要移除的罐子數量
while pq:
h, i = hq.heappop(pq) # 取出目前最低的飲料塔高度 h、位置 i
if i != A-1 and hs[i+1] - h > C: # 跟右邊比較高度差,如果右邊較高則降低高度
num = hs[i+1] - h - C # 要移除的罐子數量
ans += num
hs[i+1] -= num
hq.heappush(pq, (hs[i+1], i+1))
if i != 0 and hs[i-1] - h > C: # 跟左邊比較高度差,如果左邊較高則降低高度
num = hs[i-1] - h - C
ans += num
hs[i-1] -= num
hq.heappush(pq, (hs[i-1], i-1))
# end of while loop
print(ans)
```
### C++ 程式碼
要使用 long long 才不會溢位,執行時間最久約為 0.3 s,使用記憶體最多約為 19.6 MB,通過測試。
```cpp=
#include <iostream>
#include <queue>
#include <vector>
#include <utility>
typedef long long LL;
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
LL A, B, C; cin >> A >> B >> C; // 飲料塔數量 A,一個飲料罐的高度 B,最大高度差 C
C = (C - C%B) / B; // 改成對應的飲料罐數量,例如 B = 2, C = 5,修改成 C = 2
vector<LL> hs (A); // 每個飲料塔原來的飲料罐數量
priority_queue<pair<LL, LL>, vector<pair<LL, LL>>, greater<pair<LL, LL>>> pq; // (h, i) 由小到大排序
for(LL i=0; i<A; i++) {
LL h; cin >> h;
hs[i] = h/B;
pq.push(make_pair(h/B, i));
}
LL ans = 0; // 要移除的罐子數量
while(!pq.empty()) {
LL h = pq.top().first, i = pq.top().second; pq.pop(); // 取出目前最低的飲料塔高度 h、位置 i
if (i != A-1 && hs[i+1] - h > C) { // 跟右邊比較高度差,如果右邊較高則降低高度
LL num = hs[i+1] - h - C; // 要移除的罐子數量
ans += num;
hs[i+1] -= num;
pq.push(make_pair(hs[i+1], i+1));
}
if (i != 0 && hs[i-1] - h > C) { // 跟左邊比較高度差,如果左邊較高則降低高度
LL num = hs[i-1] - h - C;
ans += num;
hs[i-1] -= num;
pq.push(make_pair(hs[i-1], i-1));
}
}
cout << ans << "\n";
return 0;
}
```
## [ZeroJudge: b231. TOI2009 第三題:書](https://zerojudge.tw/ShowProblem?problemid=b231)
因為只有一台印刷機,所有書藉印刷的時間都要算進答案中,決定花費總時間的關鍵為裝釘時間。如果將每本書印刷、裝釘時間組成 tuple,依照裝釘時間由大到小排序。計算答案 ans 時先預設為 0,由大到小依序取出每本書的資料,答案會是 **ans 及 (前一次印刷花費的總時間 + 這次印刷花費的時間 + 這本書裝釘需要的時間) 之中較大者** 。
### Python 程式碼
寫法1,使用 list 及 sorted,執行時間最久約為 23 ms,使用記憶體最多約為 3.4 MB,通過測試。
```python=
import sys
for line in sys.stdin:
if line.isspace(): continue # 用來跳過空行
n = int(line)
pb = sorted([tuple(map(int, input().split())) for _ in range(n)],
key=lambda x : x[1], reverse=True)
t, ans = 0, 0
for p, b in pb:
t += p
ans = max(ans, t+b)
print(ans, end="\n\n")
```
寫法2,使用 heapq,執行時間最久約為 24 ms,使用記憶體最多約為 3.4 MB,通過測試。
```python=
import sys
import heapq as hq
for line in sys.stdin:
if line.isspace(): continue
n = int(line)
pb = []
for _ in range(n):
p, b = map(int, input().split())
pb.append((-b, -p)) # 要反過來並加負號
hq.heapify(pb) # priority queue 依照裝釘時間由大到小排序
t, ans = 0, 0
while pb:
b, p = hq.heappop(pb)
b = -b; p = -p
t += p
ans = max(ans, t+b)
print(ans, end="\n\n")
```
### C++ 程式碼
寫法1,使用 vector 及 sort,執行時間最久約為 2 ms,使用記憶體最多約為 356 kB,通過測試。
```cpp=
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n;
while(cin >> n) {
vector<pair<int, int>> bp;
int p, b;
for(int i=0; i<n; i++) {
cin >> p >> b;
bp.push_back(make_pair(b, p)); // 反過來在排序時比較方便
}
sort(bp.begin(), bp.end(), greater<pair<int, int>>());
int t = 0, ans = 0;
for(auto d : bp) {
t += d.second;
ans = max(ans, t + d.first);
}
cout << ans << "\n\n";
}
return 0;
}
```
如果在上方程式碼的第15行沒有把裝釘時間 b 放在前面,而是把印刷時間 p 放在前面,第17行排序時就要用 lambda function 寫比較式,會比較麻煩。執行時間最久約為 2 ms,使用記憶體最多約為 356 kB,通過測試。
```cpp=
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n;
while(cin >> n) {
vector<pair<int, int>> pb;
int p, b;
for(int i=0; i<n; i++) {
cin >> p >> b;
pb.push_back(make_pair(p, b));
}
sort(pb.begin(), pb.end(), [](pair<int, int> a, pair<int, int> b) {
return a.second > b.second; });
int t = 0, ans = 0;
for(auto d : pb) {
t += d.first;
ans = max(ans, t + d.second);
}
cout << ans << "\n\n";
}
return 0;
}
```
寫法2,使用 priority queue,執行時間最久約為 2 ms,使用記憶體最多約為 348 kB,通過測試。
```cpp=
#include <iostream>
#include <queue>
#include <utility>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n;
while(cin >> n) {
priority_queue<pair<int, int>> bp;
int p, b;
for(int i=0; i<n; i++) {
cin >> p >> b;
bp.push(make_pair(b, p)); // 一定要反過來才行
}
int t = 0, ans = 0;
while(!bp.empty()) {
int bt = bp.top().first, pt = bp.top().second;
bp.pop();
t += pt;
ans = max(ans, t + bt);
}
cout << ans << "\n\n";
}
return 0;
}
```
## [ZeroJudge: d980. 11479 - Is this the easiest problem?](https://zerojudge.tw/ShowProblem?problemid=d980)
**注意,測資中的邊長可能是 0 或負數,這樣也不能構成三角形。** 因為邊長已經由小到大排序,檢查最小的邊即可。
### Python 程式碼
執行時間最久約為 17 ms,使用記憶體最多約為 3.3 MB,通過測試。
```python=
n = int(input())
for i in range(1, n+1):
print(f"Case {i:d}: ", end="")
d = sorted(list(map(int, input().split())))
if d[0] <= 0 or d[0] + d[1] <= d[2] or d[2] - d[1] >= d[0]:
print("Invalid")
elif d[0] == d[1] == d[2]:
print("Equilateral")
elif d[0] == d[1] or d[1] == d[2]:
print("Isosceles")
else:
print("Scalene")
```
### C++ 程式碼
要使用 long long,否則在計算邊長相加時會溢位。執行時間最久約為 2 ms,使用記憶體最多約為 324 kB,通過測試。
```cpp=
#include <iostream>
#include <vector>
#include <algorithm>
typedef long long LL;
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int n; cin >> n;
for(int i=1; i<=n; i++) {
cout << "Case " << i << ": ";
vector<LL> d (3);
for(int j=0; j<3; j++) cin >> d[j];
sort(d.begin(), d.end());
if (d[0] <= 0 || d[0] + d[1] <= d[2] || d[2] - d[1] >= d[0]) {
cout << "Invalid\n";
} else if (d[0] == d[1] && d[1] == d[2]) {
cout << "Equilateral\n";
} else if (d[0] == d[1] || d[1] == d[2]) {
cout << "Isosceles\n";
} else {
cout << "Scalene\n";
}
}
return 0;
}
```
## [ZeroJudge: e446. 排列生成](https://zerojudge.tw/ShowProblem?problemid=e446)
### Python 程式碼
遞迴解,第8筆測資開始超時。
```python=
def perm(depth, maxDepth, nums, tested):
if depth == maxDepth:
print(*nums)
return
for i in range(1, N+1):
if i in tested: continue
tested.add(i)
nums.append(i)
perm(depth+1, maxDepth, nums, tested)
tested.remove(i)
nums.pop()
N = int(input())
perm(0, N, [], set())
```
### C++ 程式碼
遞迴解,執行時間最久約為 9.3 s,使用記憶體最多約為 344 kB,通過測試。
```cpp=
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int N;
void perm(int depth, int maxDepth, vector<int>& nums, set<int>& tested) {
if (depth == maxDepth) {
for(int i=0; i<(int)nums.size(); i++)
cout << nums[i] << " \n"[i == (int)nums.size()-1];
return;
}
for(int i=1; i<=N; i++) {
if (tested.count(i) == 1) continue;
tested.insert(i);
nums.push_back(i);
perm(depth+1, maxDepth, nums, tested);
tested.erase(i);
nums.pop_back();
}
}
int main() {
ios::sync_with_stdio(0); cin.tie(0);
cin >> N;
vector<int> nums;
set<int> tested;
perm(0, N, nums, tested);
return 0;
}
```
使用 algorithm next_permutation 作弊,執行時間最久約為 7.8 s,使用記憶體最多約為 352 kB,通過測試。
```cpp=
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
ios::sync_with_stdio(0); cin.tie(0);
int N; cin >> N;
int nums[N];
for(int i=0; i<N; i++) {
nums[i] = i+1;
cout << i+1 << " \n"[i == N-1];
}
while(next_permutation(nums, nums+N)) {
for(int i=0; i<N; i++)
cout << nums[i] << " \n"[i == N-1];
}
return 0;
}
```
---
###### tags:`演算法`、`APCS`、`Python`、`C++`