Knight Moves(BFS模板)



Problem Description Input Output Sample Input  
Source    
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=10;
int vis[N][N],sx,sy,tx,ty,ans;
int dxy[8][2]= {2,1,2,-1,-2,1,-2,-1,1,-2,1,2,-1,-2,-1,2};///dxy为方向数组(相对偏移量)
struct Node
{
    int x,y,cnt;///x,y分别为横纵坐标,cnt记录起点到该位置所需的步数
};
bool in(int x,int y)///判断坐标(x,y)是否合法
{
    if(x>0&&x<=8&&y>0&&y<=8)   ///这里的范围要与主函数中的sx,tx,sy,ty范围匹配
        return true;
    return false;
}
queue<Node>que;
void bfs()
{
    Node now,next;
    now.x=sx,now.y=sy;
    now.cnt=0;
    vis[sx][sy]=1;
    que.push(now);
    while(!que.empty())
    {
        now=que.front();///now为队头
        que.pop();///删除队头
        if(now.x==tx&&now.y==ty) ///判断是否到达目标状态,若是则返回;不是,继续
        {
            ans=now.cnt;
            return ;
        }
        for(int i=0; i<8; i++) ///八个方向
        {
            int nx=now.x+dxy[i][0],ny=now.y+dxy[i][1]; ///nx,ny为向8个方向中的一个方向走后的横纵坐标
            if(in(nx,ny)&&!vis[nx][ny]) ///判断坐标是否合法并且该坐标没有标记
            {
                next.x=nx;
                next.y=ny;
                next.cnt=now.cnt+1;///步数的更新
                que.push(next);///入队
                vis[nx][ny]=1;///对此坐标进行标记
            }
        }
    }
}
int main()
{
    char str1[5],str2[5];
    while(~scanf("%s%s",str1,str2))
    {
        while(!que.empty()) ///每次使队列为空以便下次输入时使用
            que.pop();
        memset(vis,0,sizeof(vis));///标记数组vis置0
        sx=str1[0]-'a'+1;  ///这里
        tx=str2[0]-'a'+1;   ///这里
        sy=str1[1]-'0';
        ty=str2[1]-'0';
        bfs();
        printf("To get from %s to %s takes %d knight moves.\n",str1,str2,ans);
    }
    return 0;
} 双向BFS(交替逐层扩展)解法: #include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int vis[10][10],sx,sy,tx,ty,flag;
int ans1,ans2,ans,num1,num2;
int dxy[8][2]= {2,1,2,-1,-2,1,-2,-1,1,-2,1,2,-1,-2,-1,2};
struct Node
{
    int x,y,cnt;
};
queue<Node>que1,que2;
bool in(int x,int y)
{
    if(x>0&&x<=8&&y>0&&y<=8)
        return true;
    return false;
}
void dbfs(queue <Node>&que,int m,int n,int &res,int an)
{
    Node now,next;
    int x,y,stp;
    now=que.front();
    x=now.x,y=now.y;
    stp=now.cnt;
    que.pop();
    for(int i=0; i<8; i++)
    {
        int nx=now.x+dxy[i][0],ny=now.y+dxy[i][1];
        if(in(nx,ny)&&vis[nx][ny]!=m)
        {
            res=stp+1;
            if(vis[nx][ny]==n)
            {
                ans=res+an;
                flag=0;
                return ;
            }
            next.x=nx,next.y=ny;
            next.cnt=res;
            que.push(next);
            vis[nx][ny]=m;
        }
    }
}
int main()
{
    char str1[5],str2[5];
    while(~scanf("%s%s",str1,str2))
    {
        while(!que1.empty())
            que1.pop();
        while(!que2.empty())
            que2.pop();
        memset(vis,0,sizeof(vis));


        sx=str1[0]-'a'+1;
        tx=str2[0]-'a'+1;
        sy=str1[1]-'0';
        ty=str2[1]-'0';


        flag=1,ans1=ans2=ans=0;


        Node now,nn;
        now.x=sx,now.y=sy;
        now.cnt=0;
        que1.push(now);
        vis[sx][sy]=1;


        nn.x=tx,nn.y=ty;
        nn.cnt=0;
        que2.push(nn);
        vis[tx][ty]=2;
        if(sx==tx&&sy==ty)
            printf("To get from %s to %s takes 0 knight moves.\n",str1,str2);
        else
        {
            while(flag)
            {
                num1=que1.size();
                while(num1--&&flag)
                    dbfs(que1,1,2,ans1,ans2);
                num2=que2.size();
                while(num2--&&flag)
                    dbfs(que2,2,1,ans2,ans1);
            }
            printf("To get from %s to %s takes %d knight moves.\n",str1,str2,ans);
        }
    }
    return 0;
}
 
上一篇:魔板 —— BFS最小步数


下一篇:【ybtoj高效进阶 21272】生命游戏(bfs)(二分)