熱門文章

2026年4月6日 星期一

ZeroJudge 解題筆記:d088. 00127 - "Accordian" Patience

作者:王一哲
日期:2026年4月6日


ZeroJudge 題目連結:d088. 00127 - "Accordian" Patience

解題想法


這題的測資格式比較特別,如果用 Python 解題,最好用 sys.stdin.read().split() 一次讀取所有的測資,再用索引值分割,這樣會比較方便。儲存所有牌堆資料時,用可以改變長度、刪除資料的 list 及 vector 比較方便。用 while 迴圈檢查是否有可以合併的牌堆,直到沒有可以合併的牌堆為止。

Python 程式碼


使用時間約為 10 ms,記憶體約為 8.6 MB,通過測試。
def solve():
    import sys

    result = []
    data = sys.stdin.read().split()
    ptr = 0
    while ptr < len(data):
        # 停止條件
        if data[ptr] == "#": break
        # 讀取兩行測資組成牌堆
        piles = [[card] for card in data[ptr:ptr+52]]
        ptr += 52
        # 移動過程
        changed = True  # 是否有交換牌
        while changed:  # 如果有交換繼續執行
            changed = False  # 先設定為 False
            i = 1  # 從牌堆 1 開始檢查
            while i < len(piles):  # 如果 i 還沒有出界繼續執行
                # 先檢查牌堆 i 與 i-3 最上面的牌是否同花色或同數字
                if i >= 3 and (piles[i][-1][0] == piles[i-3][-1][0] or \
                               piles[i][-1][1] == piles[i-3][-1][1]):
                    piles[i-3].append(piles[i].pop())  # 牌堆 i 最上面移到牌堆 i-3
                    if not piles[i]: del piles[i]  # 如果牌堆 i 是空的,刪除
                    changed = True  # 有交換牌
                    break  # 中止迴圈
                # 檢查牌堆 i 與 i-1 最上面的牌是否同花色或同數字
                elif i >= 1 and (piles[i][-1][0] == piles[i-1][-1][0] or \
                                 piles[i][-1][1] == piles[i-1][-1][1]):
                    piles[i-1].append(piles[i].pop())  # 牌堆 i 最上面移到牌堆 i-1
                    if not piles[i]: del piles[i]  # 如果牌堆 i 是空的,刪除
                    changed = True  # 有交換牌
                    break  # 中止迴圈
                # 牌堆 i 不能交換,檢查下一張
                i += 1
        # 組合答案
        n = len(piles)  # 牌堆數量
        nums = [len(pile) for pile in piles]  # 各牌堆張數
        if n == 1:  # 只有一堆
            result.append(f"1 pile remaining: {nums[0]:d}\n")
        else:  # 不只一堆
            result.append(f"{n:d} piles remaining: " + " ".join(map(str, nums)) + "\n")
    # 輸出答案
    sys.stdout.write("".join(result))

if __name__ == "__main__":
    solve()


C++ 程式碼


2026年4月3日測試,使用時間約為 1 ms,記憶體約為 3.2 MB,通過測試。2025年7月26日測試,使用時間約為 3 ms,記憶體約為 356 kB,通過測試。兩次測試的程式碼相同,但是使用的記憶體差很多,原因不明。
#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    string card;
    while(cin >> card && card != "#") {
        vector<vector<string>> piles (52, vector<string> (1));
        piles[0][0] = card;
        for(int i=1; i<52; i++) cin >> piles[i][0];
        bool changed = true;
        while(changed) {
            changed = false;
            int i = 1;
            while(i < (int)piles.size()) {
                if (i >= 3 && (piles[i].back()[0] == piles[i-3].back()[0] ||
                               piles[i].back()[1] == piles[i-3].back()[1])) {
                    piles[i-3].push_back(piles[i].back());
                    piles[i].pop_back();
                    if (piles[i].empty()) piles.erase(piles.begin() + i);
                    changed = true;
                    break;
                } else if (i >= 1 && (piles[i].back()[0] == piles[i-1].back()[0] ||
                                      piles[i].back()[1] == piles[i-1].back()[1])) {
                    piles[i-1].push_back(piles[i].back());
                    piles[i].pop_back();
                    if (piles[i].empty()) piles.erase(piles.begin() + i);
                    changed = true;
                    break;
                }
                i++;
            }
        }
        int n = (int)piles.size();
        if (n == 1) {
            cout << "1 pile remaining: " << piles[0].size() << "\n";
        } else {
            cout << n << " piles remaining:";
            for(auto pile : piles) cout << " " << pile.size();
            cout << "\n";
        }
    }
    return 0;
}


沒有留言:

張貼留言