马的遍历
题目描述
有一个 n×m 的棋盘,在某个点 (x,y) 上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步。
输入格式
输入只有一行四个整数,分别为 n,m,x,y。
输出格式
一个 n×m 的矩阵,代表马到达某个点最少要走几步(不能到达则输出 −1)。
输入输出样例
输入 #1
3 3 1 1
输出 #1
0 3 2
3 -1 1
2 1 4
说明/提示
数据规模与约定
对于全部的测试点,保证 1≤x≤n≤400,1≤y≤m≤400。
题解
马是走日字格的,这应该都知道的吧
首先本题的大致思路是从起始点出发,往八个方向走日字格,去往新的点,如果可以走到,就将那个点的步数加一,接着再从第一轮走到的点开始,往四周八个方向走日字格,如果可以走到且之前没有走到过,新走到的点的步数就等于上一个点的步数加一,再标记一下这个点走过了,接着就是这样循环,直到能到达的点全部走过一遍为止,走不到的点就是-1,最后输出棋盘上所有点的步数。
因此本题选择采用BFS的队列的思想来解决,但我这里没有用队列这个数据结构,只是用了队列的先进先出的思路。
首先要用一个二维数组来存整个棋盘(即每个点的步数),最后输出答案就是输出这个数组
int map[404][404] = { 0 };
再用一个一样大的二维数组存每个点是否被走过
int flag[404][404] = { 0 };
接着是一个用来表示队列的数组
int sq[160001][2];
这里行需要160001的原因是如果最坏情况下全部点都要入队一遍的话就是400*400=160000个点,因此需要这么多,虽然我第一次只开到40000也能过 ,两列表示点的横坐标和纵坐标。
最后,马从一个点出发,总共有八个方向可以走,用数组表示行动轨迹就是
xy[8][2] = { {1,2},{2,1},{-1,2},{-1,-2},{1,-2},{-2,-1},{-2,1},{2,-1} }
bfs函数部分
接下来就是bfs函数部分,首先设一个队头和队尾,队头初始化为0,队尾初始化为1(因为开始只有一个点)
int head = 0;
int tail = 1;
接着是while循环,条件为head < tail,意思是队不为空,head++表示入队,队头前移,取队头元素x,y坐标,并标记这个点走过了,再以这个点往八个方向扩展,不超边界且没走过的新点就入队,队尾加一,新点的步数为上一个点的步数加一,标记走过。
void bfs()
{
int head = 0;//相当于队头指针,指示队头位置
int tail = 1;//相当于队尾指针,指示队尾位置
int xx;//用来存新点横坐标
int yy;//用来存新点纵坐标
while (head < tail)//只要队不为空
{
head++;//队列头元素出队,队头位置加一(后移)
int x = sq[head][0];//取队头元素横坐标
int y = sq[head][1];//取队头元素纵坐标
flag[x][y] = 1;//标记队头的点(元素)走过了
for (int i = 0; i < 8; i++)//8个方向日字格遍历
{
xx = x + xy[i][0];
yy = y + xy[i][1];
if (xx<1 || yy<1 || xx>n || yy>m)//超边界
{
continue;
}
if (flag[xx][yy] == 1)//走过
{
continue;
}
map[xx][yy] = map[x][y] + 1;//步数加一
flag[xx][yy] = 1;//标记走过
tail++;//新点入队,队尾位置加一(后移)
sq[tail][0] = xx;//新点横坐标入队
sq[tail][1] = yy;//新点纵坐标入队
}
}
}
主函数部分
int main()
{
scanf("%d %d %d %d", &n, &m, &xxx, &yyy);
sq[1][0] = xxx;//起始点横坐标入队
sq[1][1] = yyy;//起始点纵坐标入队
bfs();
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (flag[i][j] != 1)//从没走过
{
map[i][j] = -1;
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
printf("%d ", map[i][j]);//输出棋盘
}
printf("\n");
}
return 0;
}
完整代码
#include<stdio.h>
int xy[8][2] = { {1,2},{2,1},{-1,2},{-1,-2},{1,-2},{-2,-1},{-2,1},{2,-1} };
int map[404][404] = { 0 };
int sq[40000][2];
int flag[404][404] = { 0 };
int n, m;
int xxx, yyy;
void bfs()
{
int head = 0;
int tail = 1;
int xx;
int yy;
while (head < tail)
{
head++;
int x = sq[head][0];
int y = sq[head][1];
flag[x][y] = 1;
for (int i = 0; i < 8; i++)
{
xx = x + xy[i][0];
yy = y + xy[i][1];
if (xx<1 || yy<1 || xx>n || yy>m)
{
continue;
}
if (flag[xx][yy] == 1)
{
continue;
}
map[xx][yy] = map[x][y] + 1;
flag[xx][yy] = 1;
tail++;
sq[tail][0] = xx;
sq[tail][1] = yy;
}
}
}
int main()
{
scanf("%d %d %d %d", &n, &m, &xxx, &yyy);
sq[1][0] = xxx;
sq[1][1] = yyy;
bfs();
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (flag[i][j] != 1)
{
map[i][j] = -1;
}
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
printf("%d ", map[i][j]);
}
printf("\n");
}
return 0;
}