CodeForces 1201E2 Knightmare (hard)
orz Charlie/bx.
考虑对棋盘染色,那么马移动到的格子和原来的格子异色。
进而发现若两个马初始异色,那么只有白马可以吃黑马,否则只有黑马可以吃白马。
下面只讨论初始异色的情况,同色是对称的。下文令 \(W, B, T_W, T_B\) 分别为白马起点,黑马起点,白马终点,黑马终点。
考虑若白马能比黑马早到终点,即 \(\text{dis}(W, T_W) \le \text{dis}(B, T_B)\),那么白马直接不管黑马冲到终点就行了,反正黑马也吃不掉它。
否则白马比速度肯定比不过了,就要想办法吃掉黑马。发现如果白马能比黑马早到 \(T_B\) 白马才有可能吃掉黑马。因为题目说另一只马到了终点再吃也算吃掉,所以这里的早到定义为 \(\text{dis}(W, T_B) \le \text{dis}(B, T_B) + 1\)。
那么白马到了 \(T_B\) 后如果还没吃掉黑马,那么此时白马和黑马的距离一定至少为 \(2\)(因为两只马此时位置同色)。黑马肯定不能移动使得它与白马的距离为 \(1\),否则白马就吃掉它了。所以黑马只能移动使得它与白马的距离为 \(3\)。又因为 \(\text{dis}(T_W, T_B) = 3\),所以白马直接冲到终点就结束了。
如果不满足 \(\text{dis}(W, T_B) \le \text{dis}(B, T_B) + 1\) 那么白马无法吃掉黑马。这种情况黑马直接冲到终点就能赢,不用管白马。
直接模拟上面的分析过程即可。实现时需要以 \(W, B\) 为起点跑最短路并且记录一下前驱。
code
// Problem: E2. Knightmare (hard)
// Contest: Codeforces - Codeforces Round 577 (Div. 2)
// URL: https://codeforces.com/problemset/problem/1201/E2
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<int, int> pii;
const int maxn = 1010;
const int dx[] = {-2, -2, -1, -1, 1, 1, 2, 2};
const int dy[] = {1, -1, 2, -2, 2, -2, 1, -1};
int n, m, xa, ya, xb, yb, fa[maxn][maxn], fb[maxn][maxn];
pii ga[maxn][maxn], gb[maxn][maxn];
inline pii get() {
int x, y;
scanf("%d%d", &x, &y);
return mkp(x, y);
}
inline void put(int x, int y) {
printf("%d %d\n", x, y);
fflush(stdout);
}
inline bool check(int xa, int ya, int xb, int yb) {
for (int i = 0; i < 8; ++i) {
if (xa + dx[i] == xb && ya + dy[i] == yb) {
return 1;
}
}
return 0;
}
void solve() {
scanf("%d%d%d%d%d%d", &n, &m, &xa, &ya, &xb, &yb);
if (check(xa, ya, xb, yb)) {
printf("WHITE\n%d %d\n", xb, yb);
return;
}
mems(fa, -1);
mems(fb, -1);
queue<pii> q;
fa[xa][ya] = 0;
q.emplace(xa, ya);
while (q.size()) {
int x = q.front().fst, y = q.front().scd;
q.pop();
for (int i = 0; i < 8; ++i) {
int nx = x + dx[i], ny = y + dy[i];
if (nx < 1 || nx > n || ny < 1 || ny > m) {
continue;
}
if (fa[nx][ny] == -1) {
fa[nx][ny] = fa[x][y] + 1;
ga[nx][ny] = mkp(x, y);
q.emplace(nx, ny);
}
}
}
fb[xb][yb] = 0;
q.emplace(xb, yb);
while (q.size()) {
int x = q.front().fst, y = q.front().scd;
q.pop();
for (int i = 0; i < 8; ++i) {
int nx = x + dx[i], ny = y + dy[i];
if (nx < 1 || nx > n || ny < 1 || ny > m) {
continue;
}
if (fb[nx][ny] == -1) {
fb[nx][ny] = fb[x][y] + 1;
gb[nx][ny] = mkp(x, y);
q.emplace(nx, ny);
}
}
}
if ((xa + xb + ya + yb) & 1) {
if (fa[n / 2][m / 2] <= fb[n / 2 + 1][m / 2]) {
puts("WHITE");
vector<pii> vc;
int x = n / 2, y = m / 2;
while (x != xa || y != ya) {
vc.pb(x, y);
pii p = ga[x][y];
x = p.fst;
y = p.scd;
}
reverse(vc.begin(), vc.end());
for (pii p : vc) {
put(p.fst, p.scd);
if (p.fst == n / 2 && p.scd == m / 2) {
return;
}
pii q = get();
if (check(p.fst, p.scd, q.fst, q.scd)) {
put(q.fst, q.scd);
return;
}
}
} else if (fa[n / 2 + 1][m / 2] <= fb[n / 2 + 1][m / 2] + 1) {
puts("WHITE");
vector<pii> vc;
int x = n / 2 + 1, y = m / 2;
while (x != xa || y != ya) {
vc.pb(x, y);
pii p = ga[x][y];
x = p.fst;
y = p.scd;
}
reverse(vc.begin(), vc.end());
for (pii p : vc) {
put(p.fst, p.scd);
pii q = get();
if (check(p.fst, p.scd, q.fst, q.scd)) {
put(q.fst, q.scd);
return;
}
}
vector<pii>().swap(vc);
vc.pb(n / 2, m / 2 + 2);
vc.pb(n / 2 - 2, m / 2 + 1);
vc.pb(n / 2, m / 2);
for (pii p : vc) {
put(p.fst, p.scd);
if (p.fst == n / 2 && p.scd == m / 2) {
return;
}
pii q = get();
if (check(p.fst, p.scd, q.fst, q.scd)) {
put(q.fst, q.scd);
return;
}
}
} else {
puts("BLACK");
fflush(stdout);
vector<pii> vc;
int x = n / 2 + 1, y = m / 2;
while (x != xb || y != yb) {
vc.pb(x, y);
pii p = gb[x][y];
x = p.fst;
y = p.scd;
}
reverse(vc.begin(), vc.end());
for (pii p : vc) {
pii q = get();
if (check(xb, yb, q.fst, q.scd)) {
put(q.fst, q.scd);
return;
}
put(p.fst, p.scd);
xb = p.fst;
yb = p.scd;
if (p.fst == n / 2 + 1 && p.scd == m / 2) {
return;
}
}
}
} else {
if (fb[n / 2 + 1][m / 2] < fa[n / 2][m / 2]) {
puts("BLACK");
fflush(stdout);
vector<pii> vc;
int x = n / 2 + 1, y = m / 2;
while (x != xb || y != yb) {
vc.pb(x, y);
pii p = gb[x][y];
x = p.fst;
y = p.scd;
}
reverse(vc.begin(), vc.end());
for (pii p : vc) {
pii q = get();
if (check(xb, yb, q.fst, q.scd)) {
put(q.fst, q.scd);
return;
}
put(p.fst, p.scd);
xb = p.fst;
yb = p.scd;
if (p.fst == n / 2 + 1 && p.scd == m / 2) {
return;
}
}
} else if (fb[n / 2][m / 2] <= fa[n / 2][m / 2]) {
puts("BLACK");
fflush(stdout);
vector<pii> vc;
int x = n / 2, y = m / 2;
while (x != xb || y != yb) {
vc.pb(x, y);
pii p = gb[x][y];
x = p.fst;
y = p.scd;
}
reverse(vc.begin(), vc.end());
for (pii p : vc) {
pii q = get();
if (check(xb, yb, q.fst, q.scd)) {
put(q.fst, q.scd);
return;
}
put(p.fst, p.scd);
xb = p.fst;
yb = p.scd;
if (p.fst == n / 2 + 1 && p.scd == m / 2) {
return;
}
}
vector<pii>().swap(vc);
vc.pb(n / 2 + 1, m / 2 + 2);
vc.pb(n / 2 + 3, m / 2 + 1);
vc.pb(n / 2 + 1, m / 2);
for (pii p : vc) {
pii q = get();
if (check(xb, yb, q.fst, q.scd)) {
put(q.fst, q.scd);
return;
}
put(p.fst, p.scd);
xb = p.fst;
yb = p.scd;
}
} else {
puts("WHITE");
vector<pii> vc;
int x = n / 2, y = m / 2;
while (x != xa || y != ya) {
vc.pb(x, y);
pii p = ga[x][y];
x = p.fst;
y = p.scd;
}
reverse(vc.begin(), vc.end());
for (pii p : vc) {
put(p.fst, p.scd);
if (p.fst == n / 2 && p.scd == m / 2) {
return;
}
pii q = get();
if (check(p.fst, p.scd, q.fst, q.scd)) {
put(q.fst, q.scd);
return;
}
}
}
}
}
int main() {
int T = 1;
// scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}

浙公网安备 33010602011771号