[luoguP1443]马的遍历
首先来看一下题目描述:
题目描述
有一个n*m的棋盘(1<n,m<=400),在某个点上有一个马,要求你计算出马到达棋盘上任意一个点最少要走几步
输入输出格式
输入格式:
一行四个数据,棋盘的大小和马的坐标
输出格式:
一个n*m的矩阵,代表马到达某个点最少要走几步(左对齐,宽5格,不能到达则输出-1)
输入输出样例
输出样例#1:
0 3 2
3 -1 1
2 1 4
好了很明显了这是一道搜索题。那么再来分析一下:是应该用深搜还是用广搜呢?
那么再来回头看一下题目:要求输出最少的步数。这时我们就应该考虑深搜的可行性了:深搜是一次跑到底,不撞南墙不回头,那么只要搜寻到一个结果都会进行跳出,这种答案是随机的,那么在这里我们使用广搜。
首先来讲一下思路:考虑到马走日的行走规律,我们先定下一个dx和dy数组,用来储存方向。
int dx[9]={0,1,2,-1,-2,2,-1,1,-2}; int dy[9]={0,2,1,-2,-1,-1,2,-2,1};
然后是常规的一系列操作:定义地图map,进行搜索。
然后就是搜索函数search。函数的参数为x和y和ans,这里我们定义的返回时刻是一个阙值(定值),可以设定在150~200左右,因为到了这个阙值,地图必将遍历完成(由于数据范围大小的原因)。
然后就是搜索了,我们在函数里面定义一个参数ans用来记录最小步数,然后每次把map[x][y]=ans,这里的x,y是表示的当前的位置坐标,然后在不出界,map未走过的情况下,朝8个方向搜索,代码如下了:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<cmath> using namespace std; int dx[9]={0,1,2,-1,-2,2,-1,1,-2}; int dy[9]={0,2,1,-2,-1,-1,2,-2,1}; int n,m,horsex,horsey; int map[401][401]; void search(int x,int y,int ans) { if(ans>200) return ; map[x][y]=ans; for(int i=1;i<=8;i++) { if(x+dx[i]>0&&y+dy[i]>0) if(x+dx[i]<=n&&y+dy[i]<=m) if(map[x+dx[i]][y+dy[i]]==-1||map[x+dx[i]][y+dy[i]]>ans+1) search(x+dx[i],y+dy[i],ans+1); } } int main() { cin>>n>>m>>horsex>>horsey; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) map[i][j]=-1; search(horsex,horsey,0); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) printf("%-5d",map[i][j]); printf("\n"); } return 0; }