LeetCode 2029. 石子游戏

2029. 石子游戏 IX

Solution

自己思路:

一开始也是分类讨论了,不过是从价值是3的倍数的数字的个数和总和是否是3的倍数来讨论的。

正确思路:首先3的倍数的数字就是双方交替的。但是由于取完也会是Bob获胜,所以这里要讨论3的倍数cnt0的个数的奇偶性。同时要对非3的倍数细分,分为余数为1的cnt1的个数和余数为2cnt2的个数。

  • cnt0为偶数时,等同于没有:

    • Alice先拿余数为1的情况:

      两个人的最佳交替策略为:11212121212...

      Alice获胜的条件:(肯定从1开始分析,1个,多个,这样分析)

      • 恰好1个1,且2至少1个。Bob取走2,总和3的倍数,Alice胜。
      • 至少2个1的情况,不能比2多:
        • 比2多1个:Alice取完最后一个2,没有石子,Bob胜。
        • 比2多2个:Bob取完最后一个1,没有石子,Bob胜。
        • 比2多2个以上:肯定有一步,Alice没有2可取,Bob胜。
        • 一样多或2更多,肯定有一步,Bob 没有1可取,Alice胜。

      归纳获胜条件为:有1的石子,且不能比2多

    • Alice先拿余数为2的情况:

      两个人的最佳交替策略为:221212121...

      同样的方式进行归纳分析。

      归纳获胜条件为:有2的石子,且不能比1多。

    综上:获胜条件为:1的石子和2的石子都至少有1个

  • cnt1为奇数时,等同于考虑一个:

    获胜条件为Bobcnt0为偶数时,不是因为没有石子而获胜的条件。

    即为1的石子比2的石子多超过2个或者2的石子比1的石子多超过2个

class Solution {
    public boolean stoneGameIX(int[] stones) {
        int noThreeCnt = 0, threeCnt = 0;
        int noThreeSum = 0;
        for (int x: stones) {
            if (x % 3 != 0) {
                noThreeCnt++;
                noThreeSum += x;
            } else {
                threeCnt++;
            }
        }
        if (noThreeCnt <= 0) return false;
        if (noThreeSum % 3 != 0) return false;
        if (((noThreeCnt + threeCnt) & 1) != 0) {
            return false;
        } else {
            return true;
        }
    }
}
posted @ 2022-01-20 17:37  Frontierone  阅读(45)  评论(0编辑  收藏  举报