O(n) solution
If we start with 1, 2, 4 or 6 stones, A
will always win, because he'll just take them all in the first move.
If we start with 3, A
will lose no matter what he does, because regardless of whether he takes 1 or 2, B
will take 2 or 1 next and win.
If we start with 5, A
will win by taking 2 first, thus sending B
to the case above, where he starts with 3 stones.
If we start with 7, A
will win by taking 4
, sending B
to the same case with 3
.
If we start with 8, A
will lose no matter what he does: whatever he takes, he will send B
to a winning position.
If we start with 9, A
can take 1 and send B
to the situation with 8, causing him to lose.
If we start with 10, A
can take 2 and send B
to the situation with 8 again, causing him to lose.
By now, it should become quite obvious how you can incrementally build an O(n)
solution: let win[i] = true if i stones are winnable for the first person to move
We have:
win[1] = win[2] = win[4] = win[5] = win[6] = true, win[3] = false
win[x > 6] = not (win[x - 6] and win[x - 4] and win[x - 2] and win[x - 1])
For example:
win[7] = not (win[1] and win[3] and win[5] and win[6])
= not (true and false and true and true)
= not false
= true
Compute this up until the number you're interested in and that's it. No trees involved.
O(1) solution
By looking carefully at the above solution, we can derive a simple constant time solution: note that A
can only lose if he sends B
to a winning position no matter what he does, so if k - 6, k - 4, k - 2, k - 1
are all winning positions.
If you compute win
for a few values, the pattern becomes obvious:
win[k] = false if k = 3, 8, 11, 16, 19, 24, 27, 32...
=> win[k] = false iff k mod 8 == 3 or k mod 8 == 0
For 99, 99 mod 8 = 3
, so A
does not have a sure winning strategy.