Knight Moves(骑士旅行2)

poj 2243

题目大意:给出骑士的起始和终止位置,求出最少需要多少步子到达终点

解决:本来上一道这样的题已经做过了,又遇见了就再复习下吧,上一道题是双向bfs,但是使用了stl中的queue,刚开始也是用的

stl的queue但是157ms,想着还没有自己写过front,rear手工队列,于是改成了手工的,有想着改成循环队列吧,节省空间,又都改成了循环队列;

复习下循环对列的知识:length=(rear-front+MAXSIZE)%MAXSIZE; 

入队:q[rear]=new node; rear=(rear+1) %MAXSIZE;

出对:curnode=q[front]; front=(front+1)%MAXSIZE; 

#include <iostream>

#include <cstring>

using namespace std;

#define inmap(x,y) (x>=0 && x<8 && y>=0 && y<8)

char s[3],e[3];

int dx[]={1,1,-1,-1,2,2,-2,-2};

int dy[]={2,-2,2,-2,1,-1,1,-1};

int vis[2][10][10];

struct node

{

    int x,y;

    node(){}

    node(int xx,int yy):x(xx),y(yy){}

};



int dbfs()

{

    int sx=s[0]-'a';

    int sy=s[1]-'1';

    int ex=e[0]-'a';

    int ey=e[1]-'1';

    if(sx==ex && sy==ey)return 0;

    node q[2][60];

    int front[2]={0,0};

    int rear[2]={0,0};

    q[0][rear[0]++]=node(sx,sy);

    vis[0][sx][sy]=1;

    q[1][rear[1]++]=node(ex,ey);

    vis[1][ex][ey]=1;

    int now=0;

    node curnode,nxtnode;

    while(rear[0]!=front[0] || rear[1]!=front[1])

    {

        int nowg=now&1,cnt=(rear[nowg]-front[nowg]+60)%60;

        while(cnt--)

        {

            curnode=q[nowg][front[nowg]];

            front[nowg]=(front[nowg]+1)%60;

            for(int i=0;i<8;i++)

            {

                nxtnode=node(curnode.x+dx[i],curnode.y+dy[i]);

                if(inmap(nxtnode.x,nxtnode.y) && !vis[nowg][nxtnode.x][nxtnode.y])

                {

                    if(vis[nowg^1][nxtnode.x][nxtnode.y])return now+1;

                    vis[nowg][nxtnode.x][nxtnode.y]=1;

                    q[nowg][rear[nowg]]=nxtnode;

                    rear[nowg]=(rear[nowg]+1)%60;

                }

            }

        }

        now++;

     }

}

int main()

{

    while(cin>>s>>e)

    {

        memset(vis,0,sizeof(vis));

        cout<<"To get from "<<s<<" to "<<e<<" takes "<<dbfs()<<" knight moves."<<endl;

    }

    system("pause");

    return 0;

}

 

你可能感兴趣的:(move)