diff --git a/2201/220120-CN.cpp b/2201/220120-CN.cpp new file mode 100644 index 0000000..a503e03 --- /dev/null +++ b/2201/220120-CN.cpp @@ -0,0 +1,94 @@ +#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}); +} diff --git a/2201/CMakeLists.txt b/2201/CMakeLists.txt index 4d79054..487d554 100644 --- a/2201/CMakeLists.txt +++ b/2201/CMakeLists.txt @@ -3,4 +3,4 @@ PROJECT(2201) SET(CMAKE_CXX_STANDARD 23) -ADD_EXECUTABLE(2201 220120.cpp) \ No newline at end of file +ADD_EXECUTABLE(2201 220120-CN.cpp)