马的遍历
开始把马的起点入队,当前节点为马的起点,再把马走日字的几个新节点入队,拓展新节点后就能把当前节点出队。
从当前节点开始,走日字的各个节点不超过边界且未曾访问则是能入队的新节点。
新节点到起点的路径长度是当前节点到起点的路径长度加一。
#include<iostream> #include<queue> #include<cstring> int stec[500][500]; //两个方向上的位移数组 int dx[]={1,-1,1,-1,2,2,-2,-2}; int dy[]={2,2,-2,-2,-1,1,-1,1}; bool bound(int x,int y,int n,int m) { return x>0&&y>0&&x<=n&&y<=m; } void horse(int x,int y,int n,int m) { std::queue<std::pair<int,int>> Q; stec[x][y]=0;//起点可达且路径长度是0 Q.push({x,y}); while(!Q.empty()) { std::pair<int,int> u=Q.front(); Q.pop(); for(int i=0;i<8;i++) { std::pair<int,int> v(u.first+dx[i],u.second+dy[i]);//应用位移数组来拓展节点 if(bound(v.first,v.second,n,m)&&stec[v.first][v.second]==-1)//若这个节点是从曾在队列中的节点拓展而来且不超过边界,又不认为它可达则是新节点 { Q.push(v); stec[v.first][v.second]=stec[u.first][u.second]+1; } } } } void output(int n,int m) { for(int i=1;i<=n;i++,std::endl(std::cout)) for(int j=1;j<=m;j++) printf("%-5d",stec[i][j]); } int main() { memset(stec,0xff,sizeof stec);//假设所有点都不能到达,都是-1 int n,m,x,y; std::cin>>n>>m>>x>>y; horse(x,y,n,m); output(n,m); }