题目链接:洛谷1443
题目描述
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步
输入格式
一行四个数据,棋盘的大小和马的坐标
输出格式
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入输出样例
输入 #1
3 3 1 1
输出 #1
0 3 2
3 -1 1
2 1 4
题解:
十分经典的问题。搜索算法的入门题目,DFS和BFS都可以实现。
相信大家都有大致思路,但还是有一些需要注意的问题。一个是输出格式“左对齐,宽5格,不能到达则输出-1”要特殊注意,另一个是在DFS的过程中要记得剪枝,以免搜了很深结果没用,这要对答案有粗略的估计(粗略估计当棋盘大小为400*400时,答案在200以内)。
还有一些细节的写法方面的问题,在代码注释中给出解释。
代码1(DFS):
#include<cstdio>
#include<cstring>//memset 在这个库里
using namespace std;
const int maxn=500;
int n,m,x,y;
int map[maxn][maxn];
int dirx[8]={-2,-1,1,2,2,1,-1,-2},diry[8]={1,2,2,1,-1,-2,-2,-1};//八个方向,比八个if好写很多
int min(int x,int y){
return x>y?y:x;
}
void DFS(int x,int y,int depth){
if (depth>=200) return ;//剪枝
if (map[x][y]==-1) map[x][y]=depth;//首次到达
else if (depth<map[x][y]) map[x][y]=depth;//找到更优解
else if (depth>=map[x][y]) return ;
for (int i=0;i<8;i++){
int xx=x+dirx[i],yy=y+diry[i];//新的坐标
if (xx>=1 && xx<=n && yy>=1 && yy<=m) DFS(xx,yy,depth+1);
}
}
int main(){
// freopen("horse.in","r",stdin);
// freopen("horse.out","w",stdout);
scanf("%d %d %d %d",&n,&m,&x,&y);
memset(map,-1,sizeof(map));//直接初始化成-1 ,如果初始化成正无穷最后改回来也是可以的
DFS(x,y,0);
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++) printf("%-5d",map[i][j]);//这里注意输出格式 ,限制宽度
printf("\n");
}
return 0;
}
代码2(BFS):
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=500;
int n,m,x,y,cnt;
int map[maxn][maxn];
int dirx[8]={-2,-1,1,2,2,1,-1,-2},diry[8]={1,2,2,1,-1,-2,-2,-1};
struct node{
int x,y,depth;
};
queue <node> que;
void BFS(int x,int y){
map[x][y]=0;
node pushin;pushin.x=x,pushin.y=y,pushin.depth=0;
que.push(pushin);
while (!que.empty()){
node t=que.front();que.pop();
for (int i=0;i<8;i++){
int xx=t.x+dirx[i],yy=t.y+diry[i];
if (xx>=1 && xx<=n && yy>=1 && yy<=m && (map[xx][yy]==-1 || map[xx][yy]>t.depth+1)){
map[xx][yy]=t.depth+1;
pushin.x=xx,pushin.y=yy,pushin.depth=t.depth+1;
que.push(pushin);
}
}
}
}
int main(){
// freopen("horse.in","r",stdin);
// freopen("horse.out","w",stdout);
scanf("%d %d %d %d",&n,&m,&x,&y);
memset(map,-1,sizeof(map));
BFS(x,y);
for (int i=1;i<=n;i++){
for (int j=1;j<=m;j++) printf("%-5d",map[i][j]);//这里注意输出格式 ,限制宽度
printf("\n");
}
return 0;
}
本文介绍洛谷1443题目的解决方案,使用DFS和BFS算法计算马在n*m棋盘上到达任意点的最少步数,详细解析代码实现,包括剪枝优化和输出格式规范。
794

被折叠的 条评论
为什么被折叠?



