【搜索】洛谷1443马的遍历

题目链接:洛谷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;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值