您的位置:首页 > 其它

[CQOI2013]棋盘游戏

2013-05-28 16:45 429 查看
最终是没有平局的。

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

所以有人用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: