UVALive 3668 A Funny Stone Game(博弈)
Description
The funny stone game is coming. There are n piles of stones, numbered with 0, 1, 2,..., n - 1. Two persons pick stones in turn. In every turn, each person selects three piles of stones numbered i, j, k (i < j, jk and at least one stone left in pile i). Then, the person gets one stone out of pile i, and put one stone into pile j and pile k respectively. (Note: if j = k, it will be the same as putting two stones into pile j). One will fail if he can't pick stones according to the rule.
David is the player who first picks stones and he hopes to win the game. Can you write a program to help him?
The number of piles, n, does not exceed 23. The number of stones in each pile does not exceed 1000. Suppose the opponent player is very smart and he will follow the optimized strategy to pick stones.
Input
![$ \leq$](https://icpcarchive.ecs.baylor.edu/external/36/3668img1.png)
![$ \leq$](https://icpcarchive.ecs.baylor.edu/external/36/3668img1.png)
![$ \leq$](https://icpcarchive.ecs.baylor.edu/external/36/3668img1.png)
![$ \leq$](https://icpcarchive.ecs.baylor.edu/external/36/3668img1.png)
The last case is followed by a line containing a zero.
Output
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 using namespace std; 6 7 const int MAXN = 23; 8 9 int sg[MAXN + 5]; 10 bool mex[MAXN * MAXN]; 11 int n, s[MAXN]; 12 13 void build_sg() { 14 for(int i = MAXN - 1; i >= 0; --i) { 15 memset(mex, 0, sizeof(mex)); 16 for(int j = i + 1; j < MAXN; ++j) { 17 for(int k = j; k < MAXN; ++k) mex[sg[j] ^ sg[k]] = true; 18 } 19 for(int j = 0; ; ++j) 20 if(!mex[j]) {sg[i] = j; break;} 21 } 22 } 23 24 void solve() { 25 int ans = 0, *sg = ::sg + MAXN - n; 26 for(int i = 0; i < n; ++i) ans ^= sg[i] * (s[i] & 1); 27 if(ans == 0) { 28 printf(" -1 -1 -1\n"); 29 return ; 30 } 31 for(int i = 0; i < n; ++i) { 32 if(s[i] == 0) continue; 33 for(int j = i + 1; j < n; ++j) { 34 for(int k = j; k < n; ++k) { 35 if((sg[i] ^ sg[j] ^ sg[k] ^ ans) == 0) { 36 printf(" %d %d %d\n", i, j, k); 37 return ; 38 } 39 } 40 } 41 } 42 } 43 44 int main() { 45 build_sg(); 46 int cnt = 0; 47 while(scanf("%d", &n) != EOF && n) { 48 for(int i = 0; i < n; ++i) scanf("%d", &s[i]); 49 printf("Game %d:", ++cnt); 50 solve(); 51 } 52 }