#include class Solution { public: static bool stoneGameIX(const std::vector& stones) { int s[3] { static_cast(std::count_if(stones.begin(), stones.end(), [](int n){ return n % 3 == 0; })), static_cast(std::count_if(stones.begin(), stones.end(), [](int n){ return n % 3 == 1; })), static_cast(std::count_if(stones.begin(), stones.end(), [](int n){ return n % 3 == 2; })) }; /** * If now state is '1', next should take '1' and state changes to '2'. * If '2', next should take '2' and state changes to 4 --%3--> '1'. * * If s[0] % 2 == 1, Alice will take what it originally takes. * Otherwise, Alice will take what it not takes originally. * * Why? To make oneself not to fail, one must take the contrary (1 <--> 2) * of the previous take. 2 players means that one should constantly take * the pile which belongs to (in fact, if not, it fails immediately) it. * And consider '3's. Taking them does not change the sum mod 3, just like * a switch to force your opponent to take what originally "belongs to" you. * No one wants to fail. Assume that there is not any '3's, taking the pile * with fewer stones will definitely fail. If possible, one will try its * best to make its opponent to take the more one. * * After the 1st take, the one who take the pile with fewer stones fails. * * When abs(s[1] - s[2]) >= 3, Alice determines what it takes by inspecting s[0]. * In this case, Alice wins. * * Then we must consider the possibility of taking all stones. * Since abs(s[1] - s[2]) < 3, it is impossible to trigger rule I and there is no * need to consider "took all but found sum mod 3 == 0". (except s[1] == s[2]) * Taking all stones will always result the winning of Bob. Discussions below: * * Case abs(..) == 2: * Case s[0] % 2 == 0: * Alice wins: take the fewer --> Bob fails by taking sum mod 3 == 0; * Else: * Bob wins: Taking the fewer pile --> Alice takes make sum mod 3 == 0 --> Fails * Taking the more pile --> Alice takes the last one --> Fails * Case abs(..) == 1: * Case s[0] % 2 == 0: * ditto. * Else: * ditto. * Case abs(..) == 0: * Case s[0] % 2 == 0: * Taking any will result in Bob's failure: taking the last one but sum % 3 == 0. * Else: * Taking any will result in Alice's failure: ditto. * * Special: one pile is == 1. * Case s[0] % 2 == 0: * Alice take the pile with only one stone then wins. * Else: * */ if ((!s[1] && !s[2]) || (s[0] + s[1] + s[2]) == 1) return false; if (!s[1] || !s[2]) { switch (s[1] ? s[1] : s[2]) { case 0: // unreachable case 1: case 2: return false; default: return s[0] & 1; } } if (s[1] == 1 || s[2] == 1) { if (!(s[0] & 1)) return true; return (s[1] == 1 ? s[2] : s[1]) > 3; } switch (std::abs(s[1] - s[2])) { case 0: case 1: case 2: return !(s[0] & 1); default: return true; } // unreachable } }; int main() { std::vector arg(100000, 10000); return Solution::stoneGameIX({3, 1, 1, 1}); }