Poj-1915 Knight Moves-双向广度优先搜索

9人阅读 评论(0) 收藏 举报
分类:

问题描述:
Your task is to write a program to calculate the minimum number of moves needed for a knight to reach one point from another, so that you have the chance to be faster than Somurolov.
For people not familiar with chess, the possible knight moves are shown in Figure 1.

问题大意:
骑士遍历问题,给出起始位置和目标位置,问从起始位置到目标位置的最少移动次数
AC代码:

int dirx[8] = {-2,-2,-1,1,2,2,1,-1};
int diry[8] = {-1,1,2,2,1,-1,-2,-2};
struct P//位置
{
    int x;
    int y;
};
P s,e;//起始、目标
int n;
int fstep[310][310],bstep[310][310];//fstep[i][j]为正向搜索到(i,j)的步数,bstep[i][j]为逆向搜索到(i,j)的步数
int bfs_2(P s,P e)
{
    if(s.x == e.x && s.y == e.y)//特判,防止漏解
        return 0;
    queue<P> q1;//正向
    queue<P> q2;//逆向
    memset(fstep,-1,sizeof(fstep));//初始化为-1
    memset(bstep,-1,sizeof(bstep));//初始化为-1
    q1.push(s);//将起始点入队
    q2.push(e);//将目标点入队
    fstep[s.x][s.y] = 0;//更新步数
    bstep[e.x][e.y] = 0;//更新步数
    while(!q1.empty() && !q2.empty())//如果有某一个队列为空,就说明那一个方向的搜索无法进行下去,问题无解
    {
        P p,next_p;//当前点,下一个点
        if(!q1.empty())//判断队列是否为空
        {
            p = q1.front();//取队首
            q1.pop();//出队
            for(int i = 0; i <= 7; ++i)//向8个方向进行扩展
            {
                next_p.x = p.x + dirx[i];
                next_p.y = p.y + diry[i];
                if(next_p.x < 0 || next_p.x > n - 1 || next_p.y < 0 || next_p.y > n - 1)//越界
                    continue;
                if(fstep[next_p.x][next_p.y] == -1)//如果正向没有搜到此点
                {
                    q1.push(next_p);//入队
                    fstep[next_p.x][next_p.y] = fstep[p.x][p.y] + 1;//更新步数
                }
                if(bstep[next_p.x][next_p.y] != -1)//如果逆向已经搜到此点
                    return fstep[next_p.x][next_p.y] + bstep[next_p.x][next_p.y];//搜索成功
            }
        }
        if(!q2.empty())//判断队列是否为空
        {
            p = q2.front();//取队首
            q2.pop();//出队
            for(int i = 0; i <= 7; ++i)//向8个方向进行扩展
            {
                next_p.x = p.x + dirx[i];
                next_p.y = p.y + diry[i];
                if(next_p.x < 0 || next_p.x > n - 1 || next_p.y < 0 || next_p.y > n - 1)//越界
                    continue;
                if(bstep[next_p.x][next_p.y] == -1)//如果逆向没有搜到此点
                {
                    q2.push(next_p);//入队
                    bstep[next_p.x][next_p.y] = bstep[p.x][p.y] + 1;//更新步数
                }
                if(fstep[next_p.x][next_p.y] != -1)//如果正向已经搜到此点
                    return bstep[next_p.x][next_p.y] + fstep[next_p.x][next_p.y];//搜索成功
            }
        }
    }
}
int main()
{
    int _;
    cin >> _;
    while(_--)//多组数据
    {
        cin >> n >> s.x >> s.y >> e.x >> e.y;
        cout << bfs_2(s,e) << endl;
    }
    return 0;
}

解决方法:
双向广度优先搜索:从起始状态和目标状态开始,同时向中间状态扩展,如果生成了同一个状态,则搜索成功

查看评论

广度优先搜索寻找最优路径、以及双向广度搜索算法

这里是poj1915上的一道在棋盘上搜索自由路径的题目:代码如下(使用BFS):/* * 使用BFS寻找最佳路径*/#include#include#includeusing namespace st...
  • urecvbnkuhBH_54245df
  • urecvbnkuhBH_54245df
  • 2010-07-17 16:25:00
  • 3133

双向广度优先搜索(介绍)

双向广度优先搜索  广度优先搜索遵循从初始结点开始一层层扩展直到找到目标结点的搜索规则,它只能较好地解决状态不是太多的情况,承受力很有限。如果扩展结点较多,而目标结点又处在较深层,采用前文叙述的广度搜...
  • fengart
  • fengart
  • 2008-05-25 23:09:00
  • 9418

八数码问题——双向广度优先搜索解决

八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。     ...
  • u014568921
  • u014568921
  • 2015-08-18 03:14:44
  • 2668

poj 1915 Knight Moves 【双向bfs】

Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22121   ...
  • shengweisong
  • shengweisong
  • 2014-10-21 13:29:09
  • 804

POJ 1915 Knight Moves 双向BFS 入门

Description Background Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him...
  • AXuan_K
  • AXuan_K
  • 2014-07-30 20:50:42
  • 883

POJ1915 双向广度优先搜索

双向广度优先搜索算法:初始状态(正向搜索)和目标状态(逆向搜索)同时向中间搜,当两个方向的搜索生成同一子状态时,搜索结束;一般用来解决最小等最优问题; 如何判断是否生成了同一子状态:(1)用标记数组...
  • In_Youth
  • In_Youth
  • 2015-07-20 14:13:25
  • 273

双向广度优先搜索法

  双向广度优先搜索法   8数码问题比较简单,一般不超过30步即可求解。搜索的节点也不会超过1000000。而如下这个问题的步数是56,如果直接用广度优先搜索,节点数量会多的难以想象。#######...
  • fengart
  • fengart
  • 2008-05-25 22:56:00
  • 2252

广度优先搜索双队列通用编程模板

给出广度优先搜索的总结和具体实现
  • shineboyxxb
  • shineboyxxb
  • 2016-08-11 19:16:31
  • 318

双向广度优先搜索算法框架

双向广度优先搜索算法是对广度优先算法的一种扩展。广度优先算法从起始节点以广度优先的顺序不断扩展, 直到遇到目的节点;而双向广度优先算法从两个方向以广度优先的顺序同时扩展,一个是从起始节点开始扩展,另...
  • thudaliangrx
  • thudaliangrx
  • 2016-02-13 14:55:19
  • 3079
    个人资料
    持之以恒
    等级:
    访问量: 2万+
    积分: 2382
    排名: 1万+
    最新评论