SRM 534 500分题

EllysCheckers

Problem Statement

 Elly and Kriss play a game. The game is played on a single row that consists of N cells; we will call it the board. The cells of the board are numbered 0 through N-1, from the left to the right. Each cell of the board is either empty or occupied by a single checker. The girls take alternating turns, until one of them cannot make a move. The girl who is unable to make a move loses the game.



In each move the current player selects a cell containing a checker and performs one of the following two types of moves:
  • A step, in which the checker is moved one cell to the right. The step can only be made if the target cell is empty.
  • A jump, in which the checker jumps three cells to the right. The jump can only be made if the target cell is empty and the cells it jumped over contain two other checkers.
Once a checker reaches the rightmost cell, it disappears immediately and no longer plays any role in the game.



The initial layout of the board will be given as a String board. The i-th character ofboard will be '.' (a period) if the i-th cell is empty at the beginning, and it will be 'o' (lowercase letter o) if the i-th cell initially contains a checker. Assume that both girls play optimally. Return "YES" (quotes for clarity) if the first player wins the game and "NO" otherwise.
 

Definition

 
Class:EllysCheckers
Method:getWinner
Parameters:String
Returns:String
Method signature:String getWinner(String board)
(be sure your method is public)
 
 
 

Notes

-If there is a checker on the rightmost cell in the beginning of the game, it disappears instantly (before the first move is made), as if it were never there.
-The rules of the game ensure that each cell contains at most one checker at any time, and that no checker can jump beyond the last cell.
 

Constraints

-board will contain between 1 and 20 characters, inclusive.
-Each character of board will be either '.' or 'o'.
 

Examples

0) 
 
".o..."
Returns: "YES"
With only one checker it is pretty obvious who will win.
1) 
 
"..o..o"
Returns: "YES"
Don't forget to ignore checkers on the rightmost cell.
2) 
 
".o...ooo..oo.."
Returns: "NO"
Here one can jump the checker from cell 5 to cell 8.
3) 
 
"......o.ooo.o......"
Returns: "YES"
 
4) 
 
".o..o...o....o.....o"
Returns: "NO"
 

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2010, TopCoder, Inc. All rights reserved.

Initially, this problem was 2D on a board 50 by 50, however, we decided to use an easier version for division 2. In the end we used the easier version for both divisions, since it allowed multiple solutions, which I've always considered a good thing.

First, let's see what can we do for small number of checkers. If their number is 0 it's obvious that the first player loses. If they are one, all moves are predetermined and the first player wins only if the distance between the checker and the end cell is odd. If there are two checkers jumps are still not possible, so the winner is also predetermined no matter what the moves of players are. In this case the sum of moves of both checkers to the last cell should be odd. Now let's see what happens if there are 3 checkers. If during the whole game no jumps are made, the winner is predetermined (because of the same observations made for 0, 1 and 2 checkers). Otherwise there are limited number of jumps that can be made - sooner or later a checker will end up in the last cell and no more jumps will be possible. So, if after that happens the sum of distances between all remaining checkers and the end cell is odd then the first player will win, otherwise the second player will win. Whether a number is odd or even (i.e. its remainder when divided by two) is called "parity" of the number. Let's see what happens to the parity of the sum when each of the possible moves is done. If a walk move is done, then the sum is reduced by one and its parity changes. If a jump move is done, then the sum is reduced by 3 and its parity also changes (since both 1 and 3 are odd numbers). But as we said earlier, only the parity of the sum matters for determining the winner if no other jump moves are done. Also the number of jumps is finite and each jump leaves the parity of the sum as a walk move would do. So we actually just proved (for 3 checkers) that only the parity of the sum of initial distances between the given checkers and the end cell matters, choosing an optimal move does not (since there isn't any difference between the moves at all). We can use induction to prove the same for larger number of checkers. However, contestants didn't have to "prove" that this solution works - their instinct was quite enough. This was the intended solution for the 2D version and the "easy" solution to the final version. Its complexity was O(N), where N is the number of cells of the board.

Now let's see what alternatives were there. The problem can be seen as a standard min/max game. If we represent the states of the game as a graph, it is a DAG, thus we can mark each state as either winning or losing position. From each position, we try all possible moves and if one of them takes the opponent in a losing position, then the current position is a winning position. If none does, then the current position is a losing position. This could be relatively easily implemented with bitmask dynamic programming (keeping the state of the board in a 20-bit integer, each bit being 0 for an empty cell and 1 for a checker). Actually, the constraints were so low, that even a bruteforce solution would work. Tests were easy to make and these exhaustive solutions were not hard to test for time limit. Now comes the interesting part. As we mentioned in the previous paragraph, the moves of the players do not matter. Because of that even not implemented correctly (for example missing jumps, or implementing an apparently wrong solution) some solution passed! The complexity of DP bitmask solution was O(2^N * N), where N is the number of cells of the board.

EllysCheckers.java
 
import java.io.*;

public class EllysCheckers
{
	public String getWinner(String board)
	{
		int parity = 0;
		for (int i = 0; i < board.length(); i++)
			if (board.charAt(i) == 'o') parity += (board.length() - i - 1);
                return (parity % 2 == 0) ? "NO" : "YES";
	}
}

Homework 1: In which cases would a "wrong" solution pass with the current statement?
  Homework 2:  Is the task still solvable if, when jumping, the two checkers over which the third one jumped disappeared? What about if the board was 50 by 50?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值