置頂

我的 VPython 教學文件 (HackMD 版本)

VPython 教學文件目錄 安裝及測試 基本語法 等速度直線運動 自由落下 終端速度 水平抛射 使用For迴圈計算水平抛射資料 斜向抛射 圓周運動 簡諧運動 單擺 木塊彈簧系統分離 重力及簡諧 行星運動 相疊木塊 雙重簡諧運動 一維彈性碰撞 ...

熱門文章

2026年8月16日 星期日

LeetCode 解題筆記:2029. Stone Game IX

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


LeetCode 題目連結:2029. Stone Game IX

解題想法


中等難度題。題目給一個整數陣列 $stones$ 代表一列石頭各自的分數,Alice 和 Bob 輪流拿石頭,如果目前行動的玩家拿走石頭時所有被移除的石頭總分為 3 的倍數,目前行動的玩家輸掉比賽;如果所有的石頭都拿光了,Alice 輸掉比賽。如果 Alice 能夠獲勝回傳 True,反之回傳 False。這題真正困難的地方在於找出 Alice 獲勝的條件,程式碼反而很簡短。由於題目只關心被移除的石頭總分是否為 3 的倍數,所以我們不需要計算總分,只要計算移除的石頭分數對 3 的餘數。先計算石頭分數對 3 取餘數為 0、1、2 的數量分別為 $a, b, c$,Alice 獲勝的狀況有以下 2 種:
  1. $a$ 為偶數且 $b > 0, c > 0$,Alice 第一回合可以拿走一顆餘數 1 或 2 的石頭,Bob 就算用餘數 0 的石頭拖時間,最後還是會拿到將總分湊成 3 的倍數的石頭。
  2. $a$ 為奇數且 $abs(b - c) > 2$,Alice 第一回合可以拿走餘數 1 及 2 的石頭之中數量較多者,Bob 就算用餘數 0 的石頭拖時間,Alice 還能夠拿一顆與第一回合相同的石頭。


Python 程式碼


Runtime: 55 ms, beats 45.80%. Memory: 30.49 MB, beats 88.55%.
class Solution:
    def stoneGameIX(self, stones: List[int]) -> bool:
        # 石頭的分數對 3 取餘數,餘數 0、1、2 的數量
        a, b, c = 0, 0, 0
        for num in stones:
            rem = num % 3
            if rem == 0: a += 1
            elif rem == 1: b += 1
            else: c += 1
        # 狀況1,a 是偶數,如果 b, c 都大於 0,第1回合可以任意選 b 或 c,Alice 勝
        # 狀況2,a 是奇數,如果 b, c 相差大於 2,Alice 勝
        if a % 2 == 0:
            return b > 0 and c > 0  
        else:
            return abs(b - c) > 2


C++ 程式碼


Runtime: 1 ms, beats 82.74%. Memory: 131.32 MB, beats 33.50%.
class Solution {
public:
    bool stoneGameIX(vector<int>& stones) {
        // 石頭的分數對 3 取餘數,餘數 0、1、2 的數量
        int a = 0, b = 0, c = 0;
        for(int num : stones) {
            int rem = num % 3;
            if (rem == 0) a++;
            else if (rem == 1) b++;
            else c++;
        }
        // 狀況1,a 是偶數,如果 b, c 都大於 0,第1回合可以任意選 b 或 c,Alice 勝
        // 狀況2,a 是奇數,如果 b, c 相差大於 2,Alice 勝
        if (a % 2 == 0) {
            return b > 0 && c > 0;  
        } else {
            return abs(b - c) > 2;
        }
    }
};


C 語言程式碼


Runtime: 9 ms, beats 20.00%. Memory: 18.16 MB, beats 80.00%.
bool stoneGameIX(int* stones, int stonesSize) {
    // 石頭的分數對 3 取餘數,餘數 0、1、2 的數量
    int a = 0, b = 0, c = 0;
    for(int i = 0; i < stonesSize; i++) {
        int rem = stones[i] % 3;
        if (rem == 0) a++;
        else if (rem == 1) b++;
        else c++;
    }
    // 狀況1,a 是偶數,如果 b, c 都大於 0,第1回合可以任意選 b 或 c,Alice 勝
    // 狀況2,a 是奇數,如果 b, c 相差大於 2,Alice 勝
    if (a % 2 == 0) {
        return b > 0 && c > 0;  
    } else {
        return abs(b - c) > 2;
    }
}


沒有留言:

張貼留言