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号