pku 1915 Knight Moves(双向广度优先搜索)

来源:互联网 发布:淘宝买到阿普唑仑片 编辑:程序博客网 时间:2024/06/05 10:17

  题意比较简单,就是模仿马在国际象棋棋盘的动作,给出起始点和终点,求最少步数

 

先用 BFS写了一遍过了,然后看到不少人提到双向BFS ,看了后重新写了一遍

 

其实双广也并不难,理解了也很容易写出来,  就是起点和终点同时开始搜索,直到发现重合点为止。

 

对于此题来说,从起点开始搜已被搜索的点vis置为1,从终点开始搜索已被搜索的点vis置为2, 

若从起点开始搜遇到vis为2的点,或者从终点开始搜遇到vis为1的点,则说明遇到重合点了,直接返回双向的步数即可。

 

第一次写,代码估计不怎么好看

 

 

 

#include <iostream>
#include <queue>
#include <stack>
using namespace std;

int vis[310][310];

struct node {
    int step;
    int x,y;
};


int si,sj;
int di,dj;
int n;

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

bool isAva(int x,int y) {
    if (x<0||x>=n||y<0||y>=n) return false;
    return true;
}


int bfs();

int main() {

    int T;
    cin>>T;
    while (T--) {
        cin>>n;
        int i,j;



        for (i=0;i<=n;++i)
            for (j=0;j<=n;++j)
                vis[i][j] = 0;

        cin>>si>>sj;
        cin>>di>>dj;
        cout<<bfs()<<endl;

    }
    return 0;
}

int bfs() {
    node s;
    s.x = si;
    s.y = sj;
    s.step = 0;

    node d;
    d.x = di;
    d.y = dj;
    d.step = 0;

    if (si==di&&sj==dj) return 0;
    vis[si][sj] = 1;
    vis[di][dj] = 2;

    int aStep = 0;
    int bStep = 0;
    queue<node> ahead;
    queue<node> back;

    ahead.push(s);
    back.push(d);
    node tmp;

    while (!ahead.empty()||!back.empty()) {
        int k;
        if (!ahead.empty()) {

            s = ahead.front();

            while (s.step==aStep) {
                ahead.pop();
                for (k=0;k<8;++k) {
                    tmp.x = s.x + dir[k][0];
                    tmp.y = s.y + dir[k][1];
                    if (isAva(tmp.x,tmp.y)) {
                        if (!vis[tmp.x][tmp.y]) {
                            vis[tmp.x][tmp.y] = 1;
                            tmp.step = s.step + 1;
                            ahead.push(tmp);
                        } else if (vis[tmp.x][tmp.y]==2) {

                            return aStep + bStep + 1;
                        }
                    }
                }//for

                if (!ahead.empty()) s = ahead.front();
                else break;

            }//while(a.step==aStep)

            ++aStep;
        }


        if (!back.empty()) {

            d = back.front();
            while (d.step ==bStep) {

                back.pop();
                for (k=0;k<8;++k) {
                    tmp.x = d.x + dir[k][0];
                    tmp.y = d.y + dir[k][1];
                    if (isAva(tmp.x,tmp.y)) {
                        if (!vis[tmp.x][tmp.y]) {
                            vis[tmp.x][tmp.y] = 2;
                            tmp.step = d.step + 1;
                            back.push(tmp);

                        } else if (vis[tmp.x][tmp.y]==1) {

                            return aStep + bStep + 1;
                        }
                    }//if(isAva)
                }//for

                if (!back.empty()) d = back.front();
                else break;

            }//while(d.setp==bStep)

            ++bStep;
        }//if(!back.empty())


    }

    return 0;
}

原创粉丝点击