马的遍历

开始把马的起点入队,当前节点为马的起点,再把马走日字的几个新节点入队,拓展新节点后就能把当前节点出队。

从当前节点开始,走日字的各个节点不超过边界且未曾访问则是能入队的新节点。

新节点到起点的路径长度是当前节点到起点的路径长度加一。

#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);
}

 

posted @ 2022-08-24 11:38  nichengmeibeiyong  阅读(24)  评论(0编辑  收藏  举报