题目
P1443 马的遍历
题目描述
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步
输入格式
一行四个数据,棋盘的大小和马的坐标
输出格式
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入输出样例
输入
3 3 1 1
输出
0 3 2
3 -1 1
2 1 4
分析
题目非常简单,基本的bfs就可以AC,需要注意的是马走的位置,自己画一画就好了。最坑的就是输出,一定要注意题目要求:左对齐,宽5格,不能到达则输出-1。
具体的解题过程可以看一看我的代码,代码有注释。
代码
//P1226
#include<cstdio>
#include<queue>
using namespace std;
typedef struct{
int x,y,s;
} site;
const int maxn = 410;
int n,m;
int chess[maxn][maxn];
site s; //起点
int vis[maxn][maxn]; //判断是否到达
int mov[8][2] = {{1,-2},{-1,-2},{-2,-1},{-2,1},{2,1},{2,-1},{1,2},{-1,2} }; //马可以走的位置
int ans[maxn][maxn]; //到达每个位置的所需的步数
void bfs(){
queue<site> q;
vis[s.x][s.y] = 1;
ans[s.x][s.y] = 0; //起点步数为0
q.push(s); //起点入队
while(!q.empty()){
site p = q.front();
q.pop();
for(int i = 0;i < 8;i++){ //遍历8个方向
int x = p.x + mov[i][0];
int y = p.y + mov[i][1];
if(x < 1 || x > n || y < 1 || y > m || vis[x][y]){ //边界判定+访问判定
continue;
}
vis[x][y] = 1;
site pp;
pp.x = x;
pp.y = y;
pp.s = p.s+1; //新坐标步数比上一节点多1
ans[x][y] = pp.s; //存储结果
q.push(pp);
}
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&s.x,&s.y);
bfs();
for(int i = 1;i <= n;i++){
for(int j = 1;j <= m;j++){
if(vis[i][j]) //可达输出步数
printf("%-5d",ans[i][j]);
else
printf("%-5d",-1); //大坑,一定要注意输出格式左对齐,每个数字宽5
}
putchar(10);
}
return 0;
}