熱門文章

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))


C++ 程式碼


使用時間約為 1 ms,記憶體約為 316 kB,通過測試。
#include <cstdio>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

int main() {
    int ca = 0, n;
    while(scanf("%d", &n) != EOF && n != 0) {
        ca++;
        vector<vector<int>> blocks;
        for(int i=0; i<n; i++) {
            vector<int> block (3);
            for(int j=0; j<3; j++) scanf("%d", &block[j]);
            sort(block.begin(), block.end());
            blocks.push_back({block[2], block[1], block[0]});
            blocks.push_back({block[2], block[0], block[1]});
            blocks.push_back({block[1], block[0], block[2]});
        }
        sort(blocks.begin(), blocks.end(), greater<vector<int>> ());
        int m = (int)blocks.size();
        vector<int> dp (m, 0);
        for(int i=0; i<m; i++) {
            int xi = blocks[i][0], yi = blocks[i][1], zi = blocks[i][2];
            dp[i] = zi;
            for(int j=0; j<i; j++) {
                int xj = blocks[j][0], yj = blocks[j][1];
                if (xj > xi && yj > yi) {
                    dp[i] = max(dp[i], dp[j]+zi);
                }
            }
        }
        int imax = *max_element(dp.begin(), dp.end());
        printf("Case %d: maximum height = %d\n", ca, imax);
    }
    return 0;
}


沒有留言:

張貼留言