1. 程式人生 > >2016年藍橋杯java B組第9題取球博弈

2016年藍橋杯java B組第9題取球博弈

import java.util.Scanner;

class Problem {
	private int N;
	private char[][][] dp;
	private int[] n = new int[3];
	private int min = Integer.MAX_VALUE;

	Problem(int N, int[] n) {
		this.N = N;
		this.n = n;
		init();
	}

	private void init() {
		dp = new char[2][N + 1][N + 1];
		for (int i = 0; i < 3; i++) {
			min = Math.min(min, n[i]);
		}
	}

	// p是player的意思
	// dp[p][A][B]表示先手方取了A個球,後手方取了B個球
	// 現在輪到玩家p,最後先手方的輸贏情況
	char dfs(int p, int A, int B) {
		if (dp[p][A][B] != '\u0000')
			return dp[p][A][B];

		// 沒有球可取了,判輸贏
		if (N - A - B < min) {
			if ((A & 1) == 1 && (B & 1) == 0) // A奇B偶,A勝
				dp[p][A][B] = '+';
			else if ((A & 1) == 0 && (B & 1) == 1) // B奇A偶,B勝
				dp[p][A][B] = '-';
			else
				dp[p][A][B] = '0'; // A沒勝B也沒勝,說明平

			return dp[p][A][B];
		}

		if (p == 0) { // 0號玩家,即先手一方
			boolean flag = false;
			for (int i = 0; i < 3; i++) {
				if (A + n[i] + B <= N) {
					// 1號玩家說他輸,即0號玩家贏
					if (dfs(1, A + n[i], B) == '+')
						return dp[0][A][B] = '+';
					// 1號玩家說平,但0號玩家可能還有能贏的選擇
					else if (dfs(1, A + n[i], B) == '0')
						flag = true;
				}
				if (flag)
					dp[0][A][B] = '0'; // 平
				else
					dp[0][A][B] = '-'; // 0號玩家輸
			}
		} else if (p == 1) { // 1號玩家,即後手一方
			boolean flag = false;
			for (int i = 0; i < 3; i++) {
				if (A + n[i] + B <= N) {
					// 0號玩家說他輸
					if (dfs(0, A, B + n[i]) == '-')
						return dp[1][A][B] = '-';
					// 0號玩家說平,但1號玩家可能還有能贏的選擇
					else if (dfs(0, A, B + n[i]) == '0')
						flag = true;
				}
			}
			if (flag)
				dp[1][A][B] = '0'; // 平
			else
				dp[1][A][B] = '+'; // 1號玩家贏
		}
		return dp[p][A][B];
	}
}

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int[] n = new int[3];
		for (int i = 0; i < 3; i++) {
			n[i] = sc.nextInt();
		}
		boolean flag = true;
		for (int x = 0; x < 5; x++) {
			int N = sc.nextInt();
			Problem pb = new Problem(N, n);
			if (flag) {
				System.out.print(pb.dfs(0, 0, 0));
				flag = false;
			} else {
				System.out.print(" " + pb.dfs(0, 0, 0));
			}
		}
		sc.close();
	}
}