有一个美丽的池塘。这个长方形的池子被分成了 M 行 N 列个方格(1≤M,N≤30)。一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是美丽、纯净、湛蓝的水。
贝西正在练习芭蕾舞,她站在一朵莲花上,想跳到另一朵莲花上去,她只能从一朵莲花跳到另一朵莲花上,既不能跳到水里,也不能跳到岩石上。 贝西的舞步很像象棋中的马步:
每次总是先横向移动 M1 (1≤M1≤30)格,再纵向移动 M2 (1≤M2≤30,M1≠M2)格,或先纵向移动 M1 格,再横向移动 M2 格。最多时,贝西会有八个移动方向可供选择。
给定池塘的布局和贝西的跳跃长度,请计算贝西从起点出发,到达目的地的跳的最小舞步数,保证输入数据中的目的地一定是可达的。
输入
第一行:四个用空格分开的整数:M,N,M1 和 M2
第二行到 M+1 行:第 i+1 行有 N 个用空格分开的整数,描述了池塘第 i 行的状态:0 为水,
1 为莲花,2 为岩石,3 为贝西所在的起点,4 为贝西想去的终点
输出
第一行:从起点跳到终点的最少舞步数
样例输入
4 5 1 2 1 0 1 0 1 3 0 2 0 4 0 1 2 0 0 0 0 0 1 0
样例输出
2
无法用方向数组,8种情况依此讨论
#include<bits/stdc++.h>
using namespace std;
int m, n, m1, m2;
int a[33][33] = {};
int vis[33][33] = {};
int sx, sy, lx, ly;
struct node
{
int x;
int y;
int count;
} f, g;
int bfs(int sx, int sy)
{
queue<node> q;
f.x = sx;
f.y = sy;
f.count = 0;
q.push(f);
vis[sx][sy]=1;
while (!q.empty()) {
f = q.front();
q.pop();
if (f.x == lx && f.y == ly) {
return f.count;
break;
}
if (f.x + m1 <= m && f.y + m2 <= n && vis[f.x + m1][f.y + m2] == 0 && a[f.x + m1][f.y + m2] == 1)
{
g.x = f.x + m1;
g.y = f.y + m2;
g.count = f.count+ 1;
q.push(g);
vis[g.x][g.y] = 1;
}
if (f.x - m1 > 0 && f.y - m2 > 0 && vis[f.x - m1][f.y - m2] == 0 && a[f.x - m1][f.y - m2] == 1)
{
g.x = f.x - m1;
g.y = f.y - m2;
g.count = f.count + 1;
q.push(g);
vis[g.x][g.y] = 1;
}
if (f.x + m1 <= m && f.y - m2 >0 && vis[f.x + m1][f.y - m2] == 0 && a[f.x + m1][f.y - m2] == 1)
{
g.x = f.x + m1;
g.y = f.y - m2;
g.count = f.count + 1;
q.push(g);
vis[g.x][g.y] = 1;
}
if (f.x - m1 >0 && f.y + m2 <= n && vis[f.x - m1][f.y + m2] == 0 && a[f.x - m1][f.y + m2] == 1)
{
g.x = f.x - m1;
g.y = f.y + m2;
g.count = f.count + 1;
q.push(g);
vis[g.x][g.y] = 1;
}
if (f.x + m2 <= m && f.y + m1 <= n && vis[f.x + m2][f.y + m1] == 0 && a[f.x + m2][f.y + m1] == 1)
{
g.x = f.x + m2;
g.y = f.y + m1;
g.count = f.count + 1;
q.push(g);
vis[g.x][g.y] = 1;
}
if (f.x - m2 >0 && f.y - m1 >0 && vis[f.x - m2][f.y - m1] == 0 && a[f.x - m2][f.y - m1] == 1)
{
g.x = f.x - m2;
g.y = f.y - m1;
g.count = f.count + 1;
q.push(g);
vis[g.x][g.y] = 1;
}
if (f.x + m2 <= m && f.y - m1 >0 && vis[f.x + m2][f.y - m1] == 0 && a[f.x + m2][f.y - m1] == 1)
{
g.x = f.x + m2;
g.y = f.y - m1;
g.count = f.count + 1;
q.push(g);
vis[g.x][g.y] = 1;
}
if (f.x - m2 >0 && f.y + m1 <= n && vis[f.x - m2][f.y + m1] == 0 && a[f.x - m2][f.y + m1] == 1)
{
g.x = f.x - m2;
g.y = f.y + m1;
g.count = f.count + 1;
q.push(g);
vis[g.x][g.y] = 1;
}
}
}
int main()
{
memset(vis, 0, sizeof(vis));
cin >> m >> n >> m1 >> m2;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
{
cin >> a[i][j];
if (a[i][j] == 3)
{
sx = i;
sy = j;
vis[i][j] = 1;
}//如果为初始位置,入队,并进行标记
if (a[i][j] == 4)
{
lx = i;
ly = j;
a[i][j] = 1;
} //记录结束位置
}
cout << bfs(sx, sy) << endl;//bfs
return 0;
}