熱門文章

2026年3月17日 星期二

ZeroJudge 解題筆記:c125. 00534 - Frogger

作者:王一哲
日期:2026年3月17日


ZeroJudge 題目連結:c125. 00534 - Frogger

解題想法


先讀取所有石頭的位置,計算任意兩個石頭之間的距離,存入二維陣列 $dist$ 之中,其中 $dist[i][j]$ 代表石頭 $i, j$ 之間的距離。 開一個陣列 $ans$,儲存到達第 $i$ 個石頭的路徑上單次跳躍距離最大值之中的最小值。接下來用一個最小優先佇列 $pq$,資料為 $(距離, 石頭索引值)$,代表到第 $i$ 顆石頭的路徑上最大的單次跳躍距離,距離最小的資料放上面。如果 $pq$ 還有資料,而且 $pq$ 最上面的石頭索引值不等於 $1$(終點),while 迴圈繼續執行。每次取出 $pq$ 最上方的資料,目前的距離 $curr$、石頭索引值 $u$,掃過石頭 $v ~(0 \leq v \leq n-1)$,取 $curr$ 與 $dist[u][v]$ 較大者為新的距離 $new_{dis}$,如果 $new_{dis} < ans[v]$,更新 $ans[v]$,並將 ${new_{dis}, v}$ 加入 $pq$。

Python 程式碼


使用時間約為 37 ms,記憶體約為 4.1 MB,通過測試。
import sys, heapq

def cal_dis(a, b):  # 計算距離用的函式
    return ((a[0] - b[0])**2 + (a[1] - b[1])**2)**0.5

ca = 0
result = []
for line in sys.stdin:
    if not line.strip(): continue
    n = int(line)  # n 顆石頭
    if n == 0: break  # 中止迴圈的條件
    ca += 1
    if ca > 1: result.append("\n")  # 從第 2 筆測資開始要先空一行
    stones = [tuple(map(float, sys.stdin.readline().split())) for _ in range(n)]  # 石頭位置
    dist = [[0.0]*n for _ in range(n)]  # 石頭之間的距離
    for i in range(n):
        for j in range(n):
            if i == j: continue
            d = cal_dis(stones[i], stones[j])
            dist[i][j] = d
            dist[j][i] = d
    ans = [float('inf')]*n  # 到達第 i 個石頭的路徑上單次跳躍距離最大值之中的最小值
    pq = [(0.0, 0)]  #  (距離, 石頭索引值),代表到第 $i$ 顆石頭的路徑上最大的單次跳躍距離
    while pq and pq[0][1] != 1:  # pq 還有資料,而且 pq 最上面的石頭索引值不等於 1
        curr, u = heapq.heappop(pq)  # 取出 pq 最上方的資料,目前的距離 curr、石頭索引值 u
        for v in range(n):  # 掃過石頭 v = 0 ~ n-1
            if v == u: continue  # 同一顆石頭,跳過
            new_dis = max(curr, dist[u][v])  # 新的距離
            if new_dis < ans[v]:  # 新的最小值
                ans[v] = new_dis  # 更新 ans[v]
                heapq.heappush(pq, (new_dis, v))  # (new_dis, v) 加入 pq
    result.append(f"Scenario #{ca:d}\nFrog Distance = {ans[1]:.3f}\n")
sys.stdout.write("".join(result))


2026年3月16日 星期一

ZeroJudge 解題筆記:c124. 00532 - Dungeon Master

作者:王一哲
日期:2026年3月16日


ZeroJudge 題目連結:c124. 00532 - Dungeon Master

解題想法


這題可以用一個三維陣列儲存地圖及步數,0 代表起點、障礙物、邊界,-1 代表還沒有走過的格子,另外在地圖的邊緣加一圈 0 當作哨兵,避免在用 BFS 找最短路徑時出界。 由於測資中有一些多餘的空行,用 Python 解題時可以用 sys.stdin.read().split() 一次讀取所有測資、拆開、存入串列,這樣可以很方便地避開空行。

Python 程式碼


使用時間約為 52 ms,記憶體約為 4.2 MB,通過測試。
import sys
from collections import deque

result = []
data = sys.stdin.read().split()
ptr = 0
while ptr < len(data):
    L, R, C = map(int, data[ptr:ptr+3])  # 迷宮的高、深、寬,對應 z、y、x 座標
    ptr += 3
    if L == 0 and R == 0 and C == 0: break  # 中止迴圈的條件
    sx, sy, sz, ex, ey, ez = 0, 0, 0, 0, 0, 0  # 起點、終點座標
    maze = [[[0]*(C+1) for _ in range(R+1)] for _ in range(L+1)]  # 迷宮,0 是起點、邊界、石頭
    """ 讀取地圖資料,-1 代表還沒有走過 """
    for z in range(L):  # 依序讀取 L 層地圖
        for y in range(R):  # 讀取 R 列地圖
            line = data[ptr]
            ptr += 1
            for x, ch in enumerate(line):  # 依序讀取此列的字元
                if ch == 'S':  # 起點,步數為 0
                    sz, sy, sx = z, y, x
                    maze[z][y][x] = 0
                elif ch == 'E':  # 終點,-1 代表還沒有走過
                    ez, ey, ex = z, y, x
                    maze[z][y][x] = -1
                elif ch == '.':  # 走道,-1 代表還沒有走過
                    maze[z][y][x] = -1
    """ BFS 找最短路徑 """
    que = deque([(sz, sy, sx)])  # que 放入起點
    find_ans = False  # 是否有解
    while que and not find_ans:  # 如果 que 還有資料而且還沒有找到答案,繼續執行
        z, y, x = que.popleft()  # 取出 que 最前面的資料
        for dz, dy, dx in ((1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1)):  # 6 方位檢查
            nz, ny, nx = z+dz, y+dy, x+dx  # 要檢查 (nz, ny, nx)
            if maze[nz][ny][nx] != -1: continue  # 如果此格不是 -1,找下一格
            maze[nz][ny][nx] = maze[z][y][x] + 1  # 設定此格步數
            if nz == ez and ny == ey and nx == ex:  # 走到終點,找到答案,中止迴圈
                find_ans = True
                break
            que.append((nz, ny, nx))  # (nz, ny, nx) 加入 que
    """ End of BFS """
    if find_ans:
        result.append(f"Escaped in {maze[ez][ey][ex]:d} minute(s).\n")
    else:
        result.append("Trapped!\n")
sys.stdout.write("".join(result))


2026年3月15日 星期日

ZeroJudge 解題筆記:c122. 00443 - Humble Numbers

作者:王一哲
日期:2026年3月15日


ZeroJudge 題目連結:c122. 00443 - Humble Numbers

解題想法


用陣列 nums 儲存 humble number,再用另外 4 個變數 i2, i3, i5, i7 記錄 nums 之中前一個 2、3、5、7 倍數對應的索引值,每次更新時計算這 4 個索引值分別乘以 2、3、5、7 的值,取其中的最小值加入 nums 之中並更新對應的索引值,當 nums 的長度等於 5842 就可以停止運算。接下來讀取測資,從 nums 之中找答案。

Python 程式碼


使用時間約為 14 ms,記憶體約為 4.6 MB,通過測試。
import sys

# 計算前 5842 個Humble Number
nums = [0, 1]  # 配合編號,開頭多一個 0
i2, i3, i5, i7 = 1, 1, 1, 1  # 2, 3, 5, 7 倍數基底的索引值
while len(nums) <= 5842:  # 當 nums 長度小於、等於 5842 時繼續執行
    nxt2 = nums[i2] * 2  # 下一個 2 的倍數
    nxt3 = nums[i3] * 3  # 下一個 3 的倍數
    nxt5 = nums[i5] * 5  # 下一個 5 的倍數
    nxt7 = nums[i7] * 7  # 下一個 7 的倍數
    nxt_num = min(nxt2, nxt3, nxt5, nxt7)  # 取以上 4 個數之中的最小值加入 nums
    nums.append(nxt_num)
    if nxt_num == nxt2: i2 += 1  # 如果是 2 的倍數更新 i2
    if nxt_num == nxt3: i3 += 1  # 如果是 3 的倍數更新 i3
    if nxt_num == nxt5: i5 += 1  # 如果是 5 的倍數更新 i5
    if nxt_num == nxt7: i7 += 1  # 如果是 7 的倍數更新 i7

def last(x):  # 數字後面接的英文
     two = x%100  # 最後兩位數
     one = x%10  # 最後一位數
     if two == 11 or two == 12 or two == 13: return "th"  # 最後兩位數是 11、12、13,回傳 th
     if one == 1: return "st"  # 最後一位數是 1,回傳 st
     if one == 2: return "nd"  # 最後一位數是 2,回傳 nd
     if one == 3: return "rd"  # 最後一位數是 3,回傳 rd
     return "th"  # 其它,回傳 th

result = []
lines = sys.stdin.readlines()
for line in lines:
    if not line.strip(): continue
    n = int(line)
    if n == 0: break
    result.append(f"The {n:d}{last(n):s} humble number is {nums[n]:d}.\n")
sys.stdout.write("".join(result))


2026年3月14日 星期六

ZeroJudge 解題筆記:c121. 00495 - Fibonacci Freeze

作者:王一哲
日期:2026年3月14日


ZeroJudge 題目連結:c121. 00495 - Fibonacci Freeze

解題想法


由於題目要求計算到費氏數列第 5000 項,需要用到大數加法,如果用 Python 解題可以直接算,如果用 C++ 則要自己寫大數加法的函式。

Python 程式碼


使用時間約為 8 ms,記憶體約為 4.1 MB,通過測試。
import sys

fib = [0]*5001
fib[1] = 1
for i in range(2, 5001):
    fib[i] = fib[i-1] + fib[i-2]

for line in sys.stdin:
    if not line.strip(): continue
    n = int(line)
    print(f"The Fibonacci number for {n:d} is {fib[n]:d}")


2026年3月13日 星期五

ZeroJudge 解題筆記:c117. 00439 - Knight Moves

作者:王一哲
日期:2026年3月13日


ZeroJudge 題目連結:c117. 00439 - Knight Moves

解題想法


為了便於計算,會將棋盤的座標改成 0-indexed。用一個二維串列記錄從起點走到每一格的步數,預設值 -1 代表未走訪,起點步數為 0,用 BFS 找步數。

Python 程式碼


使用時間約為 95 ms,記憶體約為 4.6 MB,通過測試。
import sys
from collections import deque

result = []
data = sys.stdin.read().split()
ptr = 0
while ptr < len(data):
    start, end = data[ptr:ptr+2]  # 起點,終點
    ptr += 2
    if start == end:  # 特例,不需要移動
        result.append(f"To get from {start:s} to {end:s} takes 0 knight moves.\n")
        continue
    grid = [[-1]*8 for _ in range(8)]  # 棋盤上走到每格的步數,-1 代表還沒有走過
    c1 = ord(start[0]) - ord('a')  # 起點座標 (r1, c1),改成 0-index
    r1 = int(start[1]) - 1
    c2 = ord(end[0]) - ord('a')  # 終點座標 (r2, c2),改成 0-index
    r2 = int(end[1]) - 1
    grid[r1][c1] = 0  # 起點步數 0
    que = deque([(r1, c1)])  # 待走訪佇列
    find_ans = False  # 是否找到答案
    while que and not find_ans:  # BFS,如果 que 還有資料而且還沒有找到答案,繼續執行
        r, c = que.popleft()  # 目前所在的位置 (r, c)
        for dr, dc in ((1, 2), (2, 1), (2, -1), (1, -2), (-1, -2), (-2, -1), (-2, 1), (-1, 2)):  # 八方位檢查
            nr, nc = r+dr, c+dc  # 正在檢查 (nr, nc)
            if 0 <= nr < 8 and 0 <= nc < 8 and grid[nr][nc] == -1:  # 未出界也未走訪
                grid[nr][nc] = grid[r][c] + 1  # 更新 (nr, nc) 的步數
                if nr == r2 and nc == c2:  # 走到終點
                    find_ans = True  # 已經找到答案
                    break  # 中止迴圈
                que.append((nr, nc))  # 將 (nr, nc) 加入 que
    result.append(f"To get from {start:s} to {end:s} takes {grid[r2][c2]:d} knight moves.\n")
sys.stdout.write("".join(result))


2026年3月12日 星期四

ZeroJudge 解題筆記:c116. 00438 - The Circumference of the Circle

作者:王一哲
日期:2026年3月12日


ZeroJudge 題目連結:c116. 00438 - The Circumference of the Circle

解題想法


這題考數學。假設三角形 $ABC$,三個角的對邊長度分別為 $a, b, c$,三角形面積為 $$ area = \frac{1}{2}ab \sin C $$ 假設外接圓半徑為 $R$,由正弦定理可得 $$ \frac{a}{\sin A} = \frac{b}{\sin B} = \frac{c}{\sin C} = 2R ~\Rightarrow~ \sin C = \frac{c}{2R} $$ 再代回面積公式 $$ area = \frac{1}{2} ab \cdot \frac{c}{2R} = \frac{abc}{4R} ~\Rightarrow~ R = \frac{abc}{4 area} $$ 其中三角形面積可以用海龍公式求解 $$ area = \sqrt{s(s-a)(s-b)(s-c)} ~~~~~ s = \frac{a+b+c}{2} $$ 最後在計算圓周長 $2 \pi R$ 時,$\pi$ 要用題目給的 $3.141592653589793$。

Python 程式碼


使用時間約為 7 ms,記憶體約為 2.9 MB,通過測試。
import sys, math

for line in sys.stdin:
    x1, y1, x2, y2, x3, y3 = map(float, line.split())
    a = ((x1 - x2)**2 + (y1 - y2)**2)**0.5
    b = ((x2 - x3)**2 + (y2 - y3)**2)**0.5
    c = ((x3 - x1)**2 + (y3 - y1)**2)**0.5
    s = (a+b+c) / 2
    area = (s*(s-a)*(s-b)*(s-c))**0.5
    R = a*b*c/(4*area)
    print(f"{2*3.141592653589793*R:.2f}")


2026年3月11日 星期三

ZeroJudge 解題筆記:c115. 00437 - The Tower of Babylon

作者:王一哲
日期:2026年3月11日


ZeroJudge 題目連結:c115. 00437 - The Tower of Babylon

解題想法


因為方塊可以旋轉,在讀取方塊邊長時,先將邊長排序,假設邊長依序為 $x, y, z$,將三種邊長排列方式都存入串列 blocks 之中。接下來將 blocks 依照長、寬由大到小排序,用 dp 計算最大高度。

Python 程式碼


使用時間約為 16 ms,記憶體約為 3 MB,通過測試。
import sys

ca = 0
result = []
for line in sys.stdin:
    if not line.strip(): continue
    n = int(line)  # 積木數量
    if n == 0: break  # 中止迴圈條件
    ca += 1
    blocks = []  # 可能的積木尺寸
    for _ in range(n):  # 讀取 n 行資料
        x, y, z = sorted(map(int, sys.stdin.readline().split()))  # x >= y >= z
        blocks.append((z, y, x))  # 取長、寬較大者放前面
        blocks.append((z, x, y))
        blocks.append((y, x, z))
    blocks.sort(key = lambda b : (b[0], b[1]), reverse=True)  # 依照長、寬由大到小排序
    m = len(blocks)  # 可用的積木數量
    dp = [0]*m  # 以第 i 塊為最上方的積木,累計的最大高度
    for i in range(m):  # 依序掃過第 0 ~ m-1 塊積木
        xi, yi, zi = blocks[i]  # 第 i 塊的 x、y、z 大小
        dp[i] = zi  # 如果只放第 i 塊,高度為 zi
        for j in range(i):  # 依序掃過第 0 ~ i-1 塊積木
            xj, yj = blocks[j][0], blocks[j][1]
            if xj > xi and yj > yi:  # 第 i 塊可以放在第 j 塊上面
                dp[i] = max(dp[i], dp[j] + zi)  # 取第 i 塊目前的高度、第 j 塊的高度加上 zi 較大者
    result.append(f"Case {ca:d}: maximum height = {max(dp):d}\n")
sys.stdout.write("".join(result))


2026年3月10日 星期二

ZeroJudge 解題筆記:c114. 00409 - Excuses, Excuses!

作者:王一哲
日期:2026年3月10日


ZeroJudge 題目連結:c114. 00409 - Excuses, Excuses!

解題想法


我是用集合儲存關鍵字,用串列儲存答案。讀取一行藉口之後,計算這行之中的關鍵字數量,如果數量是新的最大值,將儲存答案的串列清空、只存入這一行;如果數量等於目前的最大值,這一行加入儲存答案的串列之中。

Python 程式碼


使用時間約為 7 ms,記憶體約為 3 MB,通過測試。
import sys

ca = 0
result = []
for line in sys.stdin:
    if not line.strip(): continue
    ca += 1
    if ca > 1: result.append("\n")
    result.append(f"Excuse Set #{ca:d}\n")
    n, m = map(int, line.split())  # n 個關鍵字,m 行藉口
    keyword = {sys.stdin.readline().strip() for _ in range(n)}  # 關鍵字集合
    worst = []  # 最爛的藉口
    imax = 0  # 最爛的藉口關鍵字數量
    for _ in range(m):  # 讀取 m 行
        excuse = sys.stdin.readline().rstrip()  # 藉口
        cnt = 0  # 這個藉口的關鍵字數量
        word = []  # 暫存字母用的串列
        for c in excuse:  # 依序讀取字元 c
            if c.isalpha():  # 如果 c 是字母
                word.append(c.lower())  # 轉成小寫加入 word
            else:  # 反之,將 word 組成字串,如果是關鍵字,cnt 加 1
                if "".join(word) in keyword: cnt += 1
                word.clear()  # 漬空 word
        if "".join(word) in keyword: cnt += 1  # 最後要再結算一次
        word.clear()  # 漬空 word
        if cnt > imax:  # 如果 cnt 大於 imax
            imax = cnt  # 更新 imax
            worst = [excuse]  # 找到新的最爛藉口
        elif cnt == imax:  # 如果 cnt 等於 imax
            worst.append(excuse)  # 最爛藉口加一
    for s in worst: result.append(f"{s}\n")
sys.stdout.write("".join(result))


2026年3月9日 星期一

ZeroJudge 解題筆記:c113. 00378 - Intersecting Lines

作者:王一哲
日期:2026年3月9日


ZeroJudge 題目連結:c113. 00378 - Intersecting Lines

解題想法


直線的方程式可以寫成 $$ ax + by + c = 0 $$ 如果線上的兩個點的座標為 $(x_1, y_1)$、$(x_2, y_2)$,代入上式可得 $$ ax_1 + by_1 + c = 0 ~~~~~ ax_2 + by_2 + c = 0 $$ 兩式相減可得 $$ ax_1 - ax_2 + by_1 - by_2 = 0 ~\Rightarrow~ a(x_1 - x_2) = b(y_2 - y_1) $$ $$ a = y_2 - y_1 ~~~~~ b = x_1 - x_2 ~~~~~ c = -ax_1 - by_1 = x_1(y_1 - y_2) + y_1(x_2 - x_1) $$ 題目給定另一條直線上的座標為 $(x_3, y_3)$、$(x_4, y_4)$,則方程式 $a'x + b'y + c' = 0$ 的係數為 $$ a' = y_4 - y_3 ~~~~~ b' = x_3 - x_4 ~~~~~ c' = -a'x_3 - b'y_3 = x_3(y_3 - y_4) + y_3(x_4 - x_3) $$ 如果兩條直線平行,則 $$ \frac{a}{b} = \frac{a'}{b'} ~\Rightarrow~ ab' = a'b $$ 如果兩條直線重合,除了上式之外還要再加上另外兩個條件 $$ \frac{a}{c} = \frac{a'}{c'} ~\Rightarrow~ ac' = a'c ~~~~~ \frac{b}{c} = \frac{b'}{c'} ~\Rightarrow~ bc' = b'c $$ 如果兩條直線只有一個交點,則 $$ ab'x + bb'y + cb' - (a'bx + b'by + c'b) = 0 ~\Rightarrow~ x = \frac{c'b - cb'}{ab' - a'b} $$ $$ aa'x + ba'y + ca' - (a'ax + b'ay + c'a) = 0 ~\Rightarrow~ y = \frac{c'a - ca'}{ba' - b'a} $$

Python 程式碼


使用時間約為 7 ms,記憶體約為 2.9 MB,通過測試。
def line_equation(x1, y1, x2, y2):
    a = y2 - y1
    b = x1 - x2
    c = x1*(y1 - y2) + y1*(x2 - x1)
    return a, b, c

print("INTERSECTING LINES OUTPUT")
n = int(input())
for _ in range(n):
    x1, y1, x2, y2, x3, y3, x4, y4 = map(int, input().split())
    a, b, c = line_equation(x1, y1, x2, y2)
    ap, bp, cp = line_equation(x3, y3, x4, y4)
    if a*bp == ap*b:
        if a*cp == ap*c and b*cp == c*bp: print("LINE")
        else: print("NONE")
    else:
        x = (cp*b - c*bp) / (a*bp - ap*b)
        y = (cp*a - c*ap) / (b*ap - bp*a)
        print(f"POINT {x:.2f} {y:.2f}")
print("END OF OUTPUT")


2026年3月8日 星期日

ZeroJudge 解題筆記:c110. 00311 - Packets

作者:王一哲
日期:2026年3月8日


ZeroJudge 題目連結:c110. 00311 - Packets

解題想法


如果面積 $6 \times 6$ 的商品數量為 $n_6$,需要的箱子數量就是 $n_6$,而且沒有剩下的空間。 如果面積 $5 \times 5$ 的商品數量為 $n_5$,需要的箱子數量為 $n_5$,每一個箱子會剩下面積為 $11$ 的空間,總空間為 $11 n_5$,可以放入面積 $1 \times 1$ 的商品。 如果面積 $4 \times 4$ 的商品數量為 $n_4$,需要的箱子數量為 $n_4$,每一個箱子會剩下面積為 $20$ 的空間,總空間為 $20 n_4$,可以放入面積 $2 \times 2$ 的商品最多 $5$ 個,如果還有剩下的空間,可以再放入面積 $1 \times 1$ 的商品。下圖的 O 代表可用空間,X 代表已被面積 $4 \times 4$ 商品佔用的空間。
OOOOOO
OOOOOO
XXXXOO
XXXXOO
XXXXOO
XXXXOO
如果面積 $3 \times 3$ 的商品數量為 $n_3$,一個箱子最多可以放入 $4$ 個面積 $3 \times 3$ 的商品,需要的箱子數量 $$ p_3 = \left \lceil \frac{n_3}{4} \right \rceil $$ 如果 $n_3$ 是 $4$ 的倍數,不會有剩下的空間;如果 $mod(n_3, 4) = 1$ 剩下面積為 $27$ 的空間,可以放入面積 $2 \times 2$ 的商品最多 $5$ 個;如果 $mod(n_3, 4) = 2$ 剩下面積為 $18$ 的空間,可以放入面積 $2 \times 2$ 的商品最多 $3$ 個;如果 $mod(n_3, 4) = 3$ 剩下面積為 $9$ 的空間,可以放入面積 $2 \times 2$ 的商品最多 $1$ 個。如果還有剩下的空間,可以再放入面積 $1 \times 1$ 的商品。下圖的 O 代表可用空間,X 代表已被面積 $3 \times 3$ 商品佔用的空間。
OOOOOO     OOOOOO     XXXOOO
OOOOOO     OOOOOO     XXXOOO
OOOOOO     OOOOOO     XXXOOO
XXXOOO     XXXXXX     XXXXXX
XXXOOO     XXXXXX     XXXXXX
XXXOOO     XXXXXX     XXXXXX
如果面積 $2 \times 2$ 的商品數量為 $n_2$,一個箱子最多可以放入 $9$ 個面積 $2 \times 2$ 的商品,需要的箱子數量 $$ p_2 = \left \lceil \frac{n_2}{9} \right \rceil $$ 如果 $n_2$ 是 $9$ 的倍數,不會有剩下的空間;如果 $mod(n_2, 9) = r_2$ 剩下面積為 $36 - 4 r_2$ 的空間,可以放入面積 $1 \times 1$ 的商品。 如果面積 $1 \times 1$ 的商品數量為 $n_1$,一個箱子最多可以放入 $36$ 個面積 $1 \times 1$ 的商品,需要的箱子數量 $$ p_1 = \left \lceil \frac{n_1}{36} \right \rceil $$ 最後答案為 $ans = p_1 + p_2 + p_3 + n_4 + n_5 + n_6$


Python 程式碼


使用時間約為 10 ms,記憶體約為 3.2 MB,通過測試。
import sys

for line in sys.stdin:
    if not line.strip(): continue
    n1, n2, n3, n4, n5, n6 = map(int, line.split())
    if n1 == 0 and n2 == 0 and n3 == 0 and n4 == 0 and n5 == 0 and n6 == 0: break
    """ 放入 5*5 的商品 """
    s5 = 11*n5  # 放 5*5 商品箱子剩下的空間
    if s5 >= n1:  # 可以放入所有 1*1 商品
        s5 -= n1; n1 = 0
    else:  # 無法放入所有 1*1 商品
        n1 -= s5; s5 = 0
    """ 放入 4*4 的商品 """
    s4 = 20*n4  # 放 4*4 商品箱子剩下的空間
    if s4 >= n2*4:  # 可以放入所有 2*2 商品
        s4 -= n2*4; n2 = 0
    else:  # 無法放入所有 2*2 商品
        n2 -= s4//4; s4 = 0
    if s4 > 0 and n1 > 0:  # s4 還有空間而且還有 1*1 商品要放
        if s4 >= n1:  # 可以放入所有 1*1 商品
            s4 -= n1; n1 = 0
        else:  # 無法放入所有 1*1 商品
            n1 -= s4; s4 = 0
    """ 放入 3*3 的商品 """
    r3 = n3%4  # 沒放滿的箱子中 3*3 商品數量
    p3 = n3//4 + (r3 > 0)  # 3*3 商品使用的箱子數量
    s3 = 0  # 沒放滿的箱子剩下的面積
    if r3 == 1:  # 放 1 個 3*3 商品
        s3 = 27  # 面積剩下 27
        if n2 <= 5:  # 可以放入所有 2*2 商品
            s3 -= n2*4; n2 = 0
        else:  # 無法放入所有 2*2 商品
            s3 -= 20; n2 -= 5
    elif r3 == 2:  # 放 2 個 3*3 商品
        s3 = 18  # 面積剩下 18
        if n2 <= 3:  # 可以放入所有 2*2 商品
            s3 -= n2*4; n2 = 0
        else:  # 無法放入所有 2*2 商品
            s3 -= 12; n2 -= 3
    elif r3 == 3:  # 放 3 個 3*3 商品
        s3 = 9  # 面積剩下 9
        if n2 == 1:  # 可以放入所有 2*2 商品
            s3 -= 4; n2 = 0
        elif n2 > 1:  # 無法放入所有 2*2 商品
            s3 -= 4; n2 -= 1
    if s3 > 0 and n1 > 0:  # s3 還有空間而且還有 1*1 商品要放
        if s3 >= n1:  # 可以放入所有 1*1 商品
            s3 -= n1; n1 = 0
        else:  # 無法放入所有 1*1 商品
            n1 -= s3; s3 = 0
    """ 放入 2*2 的商品 """
    r2 = n2%9  # 沒放滿的箱子中 3*3 商品數量
    p2 = n2//9 + (r2 > 0)  # 2*2 商品使用的箱子數量
    s2 = 0 if r2 == 0 else 36 - r2*4  # 沒放滿的箱子剩下的面積
    if s2 > 0 and n1 > 0:  # s2 還有空間而且還有 1*1 商品要放
        if s2 >= n1:  # 可以放入所有 1*1 商品
            s2 -= n1; n1 = 0
        else:  # 無法放入所有 1*1 商品
            n1 -= s2; s2 = 0
    """ 放入 1*1 的商品 """
    p1 = n1//36 + (n1%36 > 0)
    """ 印出答案 """
    print(p1 + p2 + p3 + n4 + n5 + n6)