[CQOI2013]棋盘游戏

最终是没有平局的。

我们发现白方赢是只有一步吃掉黑方。

所以有人用dfs dp 过的。

我是用贝贝的方法做的。

http://tieba.baidu.com/p/2354159387

(我写的有些繁琐)

/**

 * Problem:chess

 * Author:Shun Yao

 * Time:2013.5.27

 * Result:Accepted

 * Memo:DP

 */



#include <cstring>

#include <cstdlib>

#include <cstdio>



#define MaxN (20)

#define MaxS (320000)

#define ai(a, b, c, d, e) (((((b) * MaxN + (c)) * MaxN + (d)) * MaxN + (e)) * 2 + (a))



void ia(long x, long &i, long &j, long &k, long &l, long &m) {

	m = x % 2;

	x >>= 1;

	l = x % MaxN;

	x /= MaxN;

	k = x % MaxN;

	x /= MaxN;

	j = x % MaxN;

	x /= MaxN;

	i = x % MaxN;

}



const long di[8] = {1, -1, 0, 0, 2, -2, 0, 0};

const long dj[8] = {0, 0, 1, -1, 0, 0, 2, -2};



long n, f[MaxS], g[MaxS];



bool Modify(long m, long i, long j, long k, long l, long Y) {

	if (i == k && j == l)

		return false;

	if (!m) {

		long ff = 0, gg = 0;

		for (long x = 0; x < 4; ++x) {

			long ii = i + di[x], jj = j + dj[x];

			if (ii < 0 || ii >= n || jj < 0 || jj >= n)

				continue;

			long y = ai(1, ii, jj, k, l);

			if (f[y] == 0) {

				if (ff == 0) {

					ff = 1;

					gg = g[y];

				} else if (gg > g[y])

					gg = g[y];

			} else if (!ff && f[y] == 1) {

				if (gg < g[y])

					gg = g[y];

			}

		}

		if (f[Y] != ff || g[Y] != gg + 1) {

			f[Y] = ff;

			g[Y] = gg + 1;

			return true;

		}

	} else {

		long ff = 0, gg = 0;

		for (long x = 0; x < 8; ++x) {

			long ii = k + di[x], jj = l + dj[x];

			if (ii < 0 || ii >= n || jj < 0 || jj >= n)

				continue;

			long y = ai(0, i, j, ii, jj);

			if (f[y] == 0) {

				if (ff == 0) {

					ff = 1;

					gg = g[y];

				} else if (gg > g[y])

					gg = g[y];

			} else if (!ff && f[y] == 1) {

				if (gg < g[y])

					gg = g[y];

			}

		}

		if (f[Y] != ff || g[Y] != gg + 1) {

			f[Y] = ff;

			g[Y] = gg + 1;

			return true;

		}

	}

	return false;

}



long Q[MaxS + 1], *L = Q, *R = Q;

char inq[MaxS];



int main() {

	freopen("chess.in", "r", stdin);

	freopen("chess.out", "w", stdout);

	scanf("%ld", &n);

	memset(f, 0, sizeof f);

	memset(g, 0, sizeof g);

	memset(inq, 0, sizeof inq);

	for (long i = 0; i < n; ++i)

		for (long j = 0; j < n; ++j) {

			long aa = ai(0, i, j, i, j);

			f[aa] = f[aa + 1] = 0;

			g[aa] = g[aa + 1] = 0;

			inq[*(R++) = aa] = 1;

			inq[*(R++) = aa + 1] = 1;

		}

	long i, j, k, l, m;

	while (L != R) {

		inq[*L] = 0;

		if (g[*L] == 0x7f7f7f7f) {

			++L;

			if (L > Q + MaxS)

				L = Q;

			continue;

		}

		ia(*L, i, j, k, l, m);

		if (m == 1) {

			for (long x = 0; x < 4; ++x) {

				long ii = i + di[x], jj = j + dj[x];

				if (ii < 0 || ii >= n || jj < 0 || jj >= n)

					continue;

				long y = ai(0, ii, jj, k, l);

				if (Modify(0, ii, jj, k, l, y) && !inq[y]) {

					inq[*(R++) = y] = 1;

					if (R > Q + MaxS)

						R = Q;

				}

			}

		} else {

			for (long x = 0; x < 8; ++x) {

				long ii = k + di[x], jj = l + dj[x];

				if (ii < 0 || ii >= n || jj < 0 || jj >= n)

					continue;

				long y = ai(1, i, j, ii, jj);

				if (Modify(1, i, j, ii, jj, y) && !inq[y]) {

					inq[*(R++) = y] = 1;

					if (R > Q + MaxS)

						R = Q;

				}

			}

		}

		++L;

		if (L > Q + MaxS)

			L = Q;

	}

	scanf("%ld%ld%ld%ld", &i, &j, &k, &l);

	i = ai(0, i - 1, j - 1, k - 1, l - 1);

	if (f[i] == 1)

		printf("WHITE ");

	else

		printf("BLACK ");

	printf("%ld", g[i]);

	fclose(stdin);

	fclose(stdout);

	return 0;

}

你可能感兴趣的:(游戏)