题意:
给定一个
n
×
m
n×m
n×m 的棋盘,棋盘上有一些障碍和一只中国象棋中的马。
棋盘用一个字符矩阵表示,其中
.
.
. 表示空格子,
X
X
X 表示障碍,
M
M
M 表示马。
马的移动方式和在中国象棋中一致且会被障碍鳖马脚,马不能移动到障碍上或棋盘外。
对棋盘上的每个格子,求马最少需要移动多少次才能到该格子,若不可能则输出
−
1
-1
−1 .
直接
B
F
S
BFS
BFS.
AC代码:
int n, m;
const int N = 1e2 + 5;
char mp[N][N];
int vis[N][N];
int dx[] = {-1, -2, -2, -1, 1, 2, 2, 1};
int dy[] = {2, 1, -1, -2, -2, -1, 1, 2};
string s;
struct Node
{
int x, y;
};
bool check(int x, int y)
{
if (x < 1 || x > n || y < 1 || y > m)
return false;
if (mp[x][y] == 'X' || vis[x][y] > 0)
return false;
return true;
}
void bfs(int now_x, int now_y)
{
queue<Node> q;
q.push(Node{now_x, now_y});
vis[now_x][now_y] = 1;
while (!q.empty())
{
int x = q.front().x;
int y = q.front().y;
q.pop();
for (int i = 0; i < 8; ++i)
{
int nx = x + dx[i];
int ny = y + dy[i];
if (i == 7 || i == 0)
{
if (mp[x][y + 1] == 'X')
continue;
}
if (i == 1 || i == 2)
{
if (mp[x - 1][y] == 'X')
continue;
}
if (i == 3 || i == 4)
{
if (mp[x][y - 1] == 'X')
continue;
}
if (i == 5 || i == 6)
{
if (mp[x + 1][y] == 'X')
continue;
}
if (check(nx, ny))
{
q.push(Node{nx, ny});
vis[nx][ny] = vis[x][y] + 1;
}
}
}
}
int main()
{
sdd(n, m);
mem(vis, 0);
int x, y;
rep(i, 1, n)
{
cin >> s;
rep(j, 1, m)
{
mp[i][j] = s[j - 1];
if (mp[i][j] == 'M')
x = i, y = j;
}
}
bfs(x, y);
rep(i, 1, n)
{
rep(j, 1, m)
{
cout << vis[i][j] - 1 << " ";
}
puts("");
}
return 0;
}