Question link:
Https://icpcarchive.ecs.baylor.edu/index.php? Option = com_onlinejudge & Itemid = 8 & category = 242 & page = show_problem & problem = 1669
Root: regionals 2006: Asia-Beijing |
|
Regionals 2006> Asia-Beijing 3668-a funny stone gametime limit: 3.000 seconds |
Question meaning:
There are n piles of stones. You can choose three stacks of I, J, K each time. require (I <j <= K) and the I-th heap should be at least 1. Take a stone from the I-th heap to the J-and k-th stacks. When two people play the game in turn, they will lose if they cannot perform the operation. Ask if the first person can win the game. If yes, what should he choose for the first time? If there are multiple options, the smallest Lexicographic Order will be output.
Solution:
Expansion of Nim game
First, we only consider the transfer of one stone. It is a stone in position I. Its successor State is a stone in position J and K, which is equivalent to a sub-game, the sub-Game's or value Mex (SG [J] ^ SG [k]) is the current SG value.
Find the SG value of a stone at each position. Judge whether the SG value of all stones is 0 or not. If it is 0, it indicates that it is defeated. Otherwise, the heap where the O (N ^ 3) brute force attempts to move the SG [I] to SG [J] ^ SG [K], calculate whether the status after transfer is mandatory or not.
Code:
// # Include <cspreadsheet. h> # include <iostream> # include <cmath> # include <cstdio> # include <sstream> # include <cstdlib> # include <string. h> # include <cstring> # include <algorithm> # include <vector> # include <map> # include <set> # include <stack> # include <list> # include <queue> # include <ctime> # include <bitset> # include <cmath> # define EPS 1e-6 # define INF 0x3f3f3f3f # define PI ACOs (-1.0) # define ll _ int64 # define ll Lo Ng long # define lson L, M, (RT <1) # define rson m + 1, R, (RT <1) | 1 # define M 1000000007 // # pragma comment (linker, "/Stack: 1024000000,1024000000") using namespace STD; # define maxn 33int SG [maxn], sa [maxn], n; bool Mex [111000]; int N; void Init () {n = 23; For (INT I = N; I> = 1; I --) {memset (MEX, false, sizeof (MEX); For (Int J = I + 1; j <= N; j ++) for (int K = J; k <= N; k ++) Mex [SG [J] ^ SG [k] = true; For (Int J = 0; j ++) if (! Mex [J]) {SG [I] = J; break ;}} void solve () {int ans = 0; For (INT I = 1; I <= N; I ++) ans = ans ^ (SG [n-n + I] * (SA [I] & 1); // calculate an odd number of times, 0 // printf (": % d \ n", ANS); // system ("pause"); If (! Ans) {printf ("-1-1-1 \ n"); Return ;}for (INT I = 1; I <= N; I ++) {If (! Sa [I]) continue; For (Int J = I + 1; j <= N; j ++) {for (int K = J; k <= N; k ++) {If (! (SG [n-n + I] ^ SG [n-n + J] ^ SG [n-n + k] ^ ans )) {printf ("% d \ n", I-1, J-1); // system ("pause"); Return ;}}}}} int main () {// freopen ("in.txt", "r", stdin); // freopen ("out.txt", "W", stdout); Init (); int CAS = 0; while (~ Scanf ("% d", & N) {for (INT I = 1; I <= N; I ++) scanf ("% d ", & SA [I]); printf ("game % d:", ++ CAS); solve ();} return 0 ;}
[Nim game extended SG function] uvalive 3668 a funny stone game