题目
2029.石子游戏 IX 难度:中等
Alice 和 Bob 再次设计了一款新的石子游戏。现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值。给你一个整数数组 stones
,其中 stones[i]
是第 i
个石子的价值。
Alice 和 Bob 轮流进行自己的回合,Alice 先手。每一回合,玩家需要从 stones
中移除任一石子。
- 如果玩家移除石子后,导致 所有已移除石子 的价值 总和 可以被 3 整除,那么该玩家就 输掉游戏 。
- 如果不满足上一条,且移除后没有任何剩余的石子,那么 Bob 将会直接获胜(即便是在 Alice 的回合)。
假设两位玩家均采用 最佳 决策。如果 Alice 获胜,返回 true
;如果 Bob 获胜,返回 false
。
示例 1:
输入:stones = [2,1] 输出:true 解释:游戏进行如下: - 回合 1:Alice 可以移除任意一个石子。 - 回合 2:Bob 移除剩下的石子。 已移除的石子的值总和为 1 + 2 = 3 且可以被 3 整除。因此,Bob 输,Alice 获胜。
示例 2:
输入:stones = [2] 输出:false 解释:Alice 会移除唯一一个石子,已移除石子的值总和为 2 。 由于所有石子都已移除,且值总和无法被 3 整除,Bob 获胜。
示例 3:
输入:stones = [5,1,2,4,3] 输出:false 解释:Bob 总会获胜。其中一种可能的游戏进行方式如下: - 回合 1:Alice 可以移除值为 1 的第 2 个石子。已移除石子值总和为 1 。 - 回合 2:Bob 可以移除值为 3 的第 5 个石子。已移除石子值总和为 = 1 + 3 = 4 。 - 回合 3:Alices 可以移除值为 4 的第 4 个石子。已移除石子值总和为 = 1 + 3 + 4 = 8 。 - 回合 4:Bob 可以移除值为 2 的第 3 个石子。已移除石子值总和为 = 1 + 3 + 4 + 2 = 10. - 回合 5:Alice 可以移除值为 5 的第 1 个石子。已移除石子值总和为 = 1 + 3 + 4 + 2 + 5 = 15. Alice 输掉游戏,因为已移除石子值总和(15)可以被 3 整除,Bob 获胜。
提示:
1 <= stones.length <= 105
1 <= stones[i] <= 104
题解
根据规则和题目,可以有这些小结论:
- 所谓石子的价值真正有用的是对3取模后的值,我们将移除石子价值总数记为
x
,每个石子的价值记为s=0,1,2
; - Alice想要赢,只有一种情况,就是让Bob移除石子后使得移除石子总数是3的倍数;
- 为了保证自己不输,自己要移除的石子
s
不能等于3-x
,也就是如果现在x=1
,“我”现在能选的石子s
只能是1或0; - 偶数个
s=0
相当于没有x=0
,因为都是最优走法; - 没有
s=0
,大致情况是: - 1,1,2,1,2,1…或2,2,1,2,1,2,1…;
讨论s=0
偶数个的情况:
- 如果全是
s=1
,Alice必败; - 如果全是
s=2
,Alice也必败; 如果既有
s=1
,也有s=2
, 因为A第一手之后,1和2交替进行,所以,- 两个数量相等。无论Alice选哪个,Bob最后选的和Alice一开始选的构成三的倍数,所以Alice都赢;
s=1
和s=2
不一样多。- Alice第一步选少的那个,这样,Bob就会一路选和Alice第一次一样的,直到没了Bob只好选另一个,这时候就构成了三的倍数,Bob输掉,Alice必胜;
但如果Alice选较多的那一个(假设是
s=2
),一顿交替之后,较少的s=1
没了,如果
s=2
比s=1
只多一个,Alice是最后一个,Alice输掉;如果
s=2
比s=1
多两个,Bob最后是s=1
,根据规则,依然是Bob胜利;如果
s=2
比s=1
多超过两个,当s=1
没了,Bob选s=2
,Alice只能再选s=2
,构成3的倍数,Alice输掉—就相当于前面全是s=2
的情况。
所以,Alice要选少的那个,一样多就都行。
- 综合一下:
- 如果相同,只有一种,Alice完了;
- 两种都有,选少的,一样就都可以选;
- 也就是说,只要
s=1
或s=2
有一个没有,就完了。
讨论s=0
奇数的情况:
- Alice第一步肯定不拿
s=0
; - 奇数个
s=0
有起到转换先手的作用; - 那Bob第一步也就是整个的第二回合用不用这个
s=0
呢? - 也先考虑全是
s=1
或s=2
的情况,因为这两其实等价,所以假设全是s=1
:- 如果数量只有1个或2个,那Alice必输
她都没机会让Bob取了之后构成3的倍数啊。 - 如果数量大于2个
- Bob首先就选了
s=0
,那现在的Alice就相当于之前讨论的s=0
个数是偶数且全是s=1
这种情况下的Bob,Alice赢; - Bob先不选
s=0
,那Alice不选s=0
就输了,所以肯定会选s=0
。。。Bob输了。
- Bob首先就选了
- 如果数量只有1个或2个,那Alice必输
- 所以,如果这数量超过2,Alice必胜,不然就必败
- 现在考虑既有
s=1
也有s=2
: - 非常多的
s=2
或s=1
意义不大,就用三个以内的数量来代表; s=1
和s=1
各一个(代表一样多):Alice必输啊;s=1
1个,s=2
2个(代表两个数量相差1):- Alice选
s=1
,Bob选s=0
,Alice最后回选到s=2
而输掉,Bob为了赢那肯定会选s=0
: - Alice选
s=2
,- Bob不选
s=0
,而是选了和Alice一样的s=2
,那Alice接下来选s=1
输,选s=0
,也是输; - Bob选
s=0
,那Alice接下来只能接着选s=2
,最终还是输。
- Bob不选
- Alice选
- 所以这种情况Alice必输。
- 换个角度理解这种Alice必输的情况,因为总的数量是个偶数(1个
s=1
,2个s=2
,奇数个s=0
),而Alice要赢就要让Bob自己构成3的倍数,他俩又都是高手,能撑到最后,而最后走完,总和不可能是3的倍数,所以Alice必输。 - 其实不用接着讨论数量差更大的情况了,对之前讨论的只有一种的情况,往里加一对
s=1
和s=2
就好了,效果是一样的。 - 所以综合一下:
- 其中一个没有,得相差超过2,能赢;
- 两个都有,相差两个之内,Alice输;
- 所以,只要两个数量相差超过2Alice就能赢。
代码
1 | class Solution: |