题目链接:https://acm.zcmu.edu.cn/JudgeOnline/problem.php?id=1342
题目大意
两个骑士,只能田字格走路,两个人在长为n,宽为m的平面上同时走,问他俩能否相遇。
平面包含三个元素: "." "#" "K",点表示好的平地,井号表示坏的平地,K表示骑士。
思路
跑两个bfs,记录两个骑士到ij平面需要的步数,如果他俩没有重复的地区,那肯定不会相遇。
然后如果两个能走到这块平地还不能说明他俩会相遇,也可能前脚出后脚进的情况。
所以还需要判断两个骑士到这块地的步数之差是不是偶数,如果说是偶数的话,那么快的骑士可以来回跑,他俩总会相遇的。
还有就是坏的地也可以走,也可以走的!
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ok(x, y) x >= 1 && x <= 8 && y >= 1 && y <= 8
int dx[] = {-2, -2, 2, 2};
int dy[] = {-2, 2, -2, 2};
int dep1[15][15], dep2[15][15];
char a[15][15];
struct node{
int x, y;
};
void bfs1(int x, int y){
queue<node> q;
q.push({x, y});
dep1[x][y] = 0;
while(q.size()){
node tt = q.front(); q.pop();
for(int i = 0; i < 4; i ++){
int tx = tt.x + dx[i];
int ty = tt.y + dy[i];
if(ok(tx, ty) && dep1[tt.x][tt.y] + 1 < dep1[tx][ty]){
dep1[tx][ty] = dep1[tt.x][tt.y] + 1;
q.push({tx, ty});
}
}
}
}
bool bfs2(int x, int y){
queue<node> q;
q.push({x, y});
dep2[x][y] = 0;
while(q.size()){
node tt = q.front(); q.pop();
if(dep1[tt.x][tt.y] != 0x3f3f3f3f && (dep1[tt.x][tt.y] - dep2[tt.x][tt.y]) % 2 == 0){
return true;
}
for(int i = 0; i < 4; i ++){
int tx = tt.x + dx[i];
int ty = tt.y + dy[i];
if(ok(tx, ty) && dep2[tt.x][tt.y] + 1 < dep2[tx][ty]){
dep2[tx][ty] = dep2[tt.x][tt.y] + 1;
q.push({tx, ty});
}
}
}
return false;
}
int main(){
int t; scanf("%d", &t);
while(t --){
vector<node> k;
memset(dep1, 0x3f3f3f3f, sizeof(dep1));
memset(dep2, 0x3f3f3f3f, sizeof(dep2));
for(int i = 1; i <= 8; i ++){
scanf("%s", a[i] + 1);
for(int j = 1; j <= 8; j ++){
if(a[i][j] == 'K') k.push_back({i, j});
}
}
queue<node> q;
int x, y, flag = 0;
x = k[0].x, y = k[0].y;
bfs1(x, y);
x = k[1].x, y = k[1].y;
if(bfs2(x, y)) puts("YES");
else puts("NO");
}
return 0;
}