题目: Alice 和 Bob 再次设计了一款新的石子游戏。现有一行 n 个石子,每个石子都有一个关联的数字表示它的价值。给你一个整数数组 stones ,其中 stones[i] 是第 i 个石子的价值。 Alice 和 Bob 轮流进行自己的回合,Alice 先手。每一回合,玩家需要从 stones 中移除任一石子。 如果玩家移除石子后,导致 所有已移除石子 的价值 总和 可以被 3 整除,那么该玩家就 输掉游戏 。 如果不满足上一条,且移除后没有任何剩余的石子,那么 Bob 将会直接获胜(即便是在 Alice 的回合)。 假设两位玩家均采用 最佳 决策。如果 Alice 获胜,返回 true ;如果 Bob 获胜,返回 false 。

例: 输入: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.不考虑0的情况时所取的序列有两种情况112121212…和221212121…,0可以插入在任意非首位的位置; 2.当s[0]为偶数时,若1或2个数为零,要么石头能取完,要么111,Alice会拿到3的倍数也会输,所以在此情况下,只能1和2的个数都不为0,Alice为先手且最佳决策,Alice必赢; 3.若均不为零时,Alice取少的一个则必赢,相等时取任一个均能赢; 4.当s[0]为奇数时,次序能颠倒,故当1和2个数相差大于2时,取多的一个则在颠倒次序后Alice必赢,否则就输;

解:

class Solution {

public:

bool stoneGameIX(vector& stones) {

int s[3] = {0, 0, 0};

for (int i : stones) //相当于从stones中的值逐个取出给i

++s[i % 3]; //将石子价值按照模3余数分类计数

if (s[0] % 2 == 0) //模3余数是零的个数为偶数

return s[1] != 0 && s[2] != 0; //1和2的个数都不为0且Alice为先手

return s[2] > s[1] + 2 || s[1] > s[2] + 2; //可整除3的数为奇数个,所以次序可以颠倒,只有1和2的个数相差大于2时,取多的一个Alice才可以赢

}

};

难点: 1.考虑Alice所有能赢的情况;