POJ-2505 A multiplication game
阿新 • • 發佈:2018-12-11
題意: 給定一個數n (1 < n < 4294967295)從1開始, 可以乘以 【2, 9】中的任意一個數字, 最先乘法運算後最先大於等於n的那個人勝利。 分析: 博弈問題一般先找規律。 我們發現, 當n的範圍在【2, 9】之間時, Stan必勝, 因為Stan第一輪可以乘以【2, 9】中的任意一個數字。Stan的策略是使得他的每一步都能達到N狀態。那麼他的策略就是使得他的值儘可能快的到達n。 同理當n的範圍在 【10, 18】 之間時, Ollie必勝, 因為Ollie也可以乘以【2, 9】中的任意一個數字使得他的必勝範圍為【10, 2×9】。 Ollie的策略是使得他的每一步都達到P狀態, 那麼她的策略就是值儘可能最慢到達n。
根據以上分析, 我們可以得到: 【2, 9】 N狀態, Stan必勝 【9+1, 29】P狀態, Ollie必勝 【29 + 1, 299】N狀態, Stan必勝 【299 + 1, 299*2】 P狀態, Ollie必勝
所以我們可以根據上述的規律打表然後判斷n狀態出現的奇偶性。
程式碼如下:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; //[2, 9] stan //[10, 2*9] ollie //[2*9 + 1, 2*9*9] stan //[2*9*9 + 1, 2*9*9*2] ollie long long sg[] = {2, 9, 18, 162, 324, 2916, 5832, 52488, 104976, 944784, 1889568, 17006112, 34012224, 306110016, 612220032, 5509980288 }; int main () { long long n; while (cin >> n) { int cnt = 1; for (int i = 1; i < 17; i++) { if (sg[i] < n) { cnt++; } else { break; } } cout << (cnt % 2 ? "Stan" : "Ollie") << " wins." << endl; } return 0; }