http://poj.org/problem?id=2243

问题概述:一个8*8的棋盘,给定一个起点(列a-h,行1-8)和一个终点(列a-h,行1-8),按骑士的走法(走日字),从起点到

终点最少移动多少次

输入样例:                                 对应输出:

e2 e4                                          To get from e2 to e4 takes 2 knight moves.

a1 b2                                          To get from a1 to b2 takes 4 knight moves.

b2 c3                                          To get from b2 to c3 takes 2 knight moves.

a1 h8                                          To get from a1 to h8 takes 6 knight moves.

a1 h7                                          To get from a1 to h7 takes 5 knight moves.

h8 a1                                          To get from h8 to a1 takes 6 knight moves.

b1 c3                                          To get from b1 to c3 takes 1 knight moves.

f6 f6                                           To get from f6 to f6 takes 0 knight moves.

双向BFS:

起点终点同时BFS,直到它们相交即停止,这时最短路便是交点到起点和终点的最短路之和

http://blog.csdn.net/wdkirchhoff/article/details/41121517

时间复杂度:设BFS的复杂度为n,则双向BFS的复杂度为[2*sqrt(n),n]

http://www.ihypo.net/1614.html

和BFS的不同:

1、需要两个队列

2、不仅要标记有没有走过,而且还要进行区分标记,来记录到底是从起点走到当前点的还是从终点走到当前点的

3、要设定距离数组,表示从起点到当前位置的最短距离(因为有两个起点,而在结构体里定义最短距离只能实时更

新一个值)

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
typedef struct
{int x;int y;int t;
}Point;
Point now, temp;                /*dir[i][j]为方向数组,走日字可以往8个方向走*/
int use[11][11], dp[11][11], dir[8][2] = {-1,-2,1,-2,-2,-1,2,-1,-2,1,2,1,-1,2,1,2};/*use[i][j]==1表示点(i,j)被以起点开始的广搜搜到过,use[i][j]==1表示点(i,j)被以终点开始的广搜搜到过,use[i][j]==0表示还没被搜到*//*dp[i][j]表示点(i,j)到其中一个起点的最短路(看这个点被哪个起点开始的搜索先搜到)*/
queue<Point> q1, q2;
int main(void)
{int i, x1, y1, x2, y2, ans;char c1, c2;while(scanf(" %c%1d %c%1d", &c1, &x1, &c2, &x2)!=EOF){ans = -1;memset(use, 0, sizeof(use));memset(dp, 0, sizeof(dp));y1 = c1-96;y2 = c2-96;if(x1==x2 && y1==y2)   /*当起点等于终点*/{printf("To get from %c%d to %c%d takes %d knight moves.\n", c1, x1, c2, x2, 0);continue;}now.x = x1, now.y = y1, now.t = 0;q1.push(now);   /*起点进入第一个队列*/use[now.x][now.y] = 1;now.x = x2, now.y = y2;q2.push(now);  /*终点进入第二个队列*/use[now.x][now.y] = -1;while(q1.empty()==0 || q2.empty()==0){if(q1.empty()==0)  /*如果第一个队列不为空*/{now = q1.front();q1.pop();for(i=0;i<=7;i++){temp.x = now.x+dir[i][0];temp.y = now.y+dir[i][1];temp.t = now.t+1;if(temp.x>=1 && temp.x<=8 && temp.y>=1 && temp.y<=8 && use[temp.x][temp.y]!=1) /*如果这个点还没被搜过或只被以终点开始的广搜搜过*/{if(use[temp.x][temp.y]==-1)       /*如果这个点被以终点开始的广搜搜过,说明最短路已经被找到*/{while(q1.empty()==0)q1.pop();while(q2.empty()==0)       /*两个队列全部清0*/q2.pop();ans = temp.t+dp[temp.x][temp.y]; /*算出最短路=起点与终点到当前点最短路之和*/break;}use[temp.x][temp.y] = 1;dp[temp.x][temp.y] = temp.t;q1.push(temp);}}}if(q2.empty()==0)  /*同上*/{now = q2.front();q2.pop();for(i=0;i<=7;i++){temp.x = now.x+dir[i][0];temp.y = now.y+dir[i][1];temp.t = now.t+1;if(temp.x>=1 && temp.x<=8 && temp.y>=1 && temp.y<=8 && use[temp.x][temp.y]!=-1){if(use[temp.x][temp.y]==1){while(q2.empty()==0)q2.pop();while(q1.empty()==0)q1.pop();ans = temp.t+dp[temp.x][temp.y];break;}use[temp.x][temp.y] = -1;dp[temp.x][temp.y] = temp.t;q2.push(temp);}}}}printf("To get from %c%d to %c%d takes %d knight moves.\n", c1, x1, c2, x2, ans);}return 0;
}

POJ 2243:Knight Moves(双向BFS)相关推荐

  1. poj - 2243 Knight Moves

    这题和poj 1915一样,用bfs做走马步.现在再看当时的代码,真是好幼稚啊. 1 #include <stdio.h> 2 #include <string.h> 3 in ...

  2. OpenJudge/Poj 1915 Knight Moves

    1.链接地址: http://bailian.openjudge.cn/practice/1915 http://poj.org/problem?id=1915 2.题目: 总Time Limit: ...

  3. POJ 1915 Knight Moves

    Knight Moves Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 29822 Accepted: 14013 Descri ...

  4. POJ2243 Knight Moves —— A*算法

    题目链接:http://poj.org/problem?id=2243 Knight Moves Time Limit: 1000MS   Memory Limit: 65536K Total Sub ...

  5. NUC1333 Knight Moves【DFS】

    Knight Moves 时间限制: 1000ms 内存限制: 65535KB 问题描述 A friend of you is doing research on the Traveling Knig ...

  6. hdu1372 Knight Moves BFS 搜索

    简单BFS题目 主要是读懂题意 和中国的象棋中马的走法一样,走日字型,共八个方向 我最初wa在初始化上了....以后多注意... 代码: 1 #include <iostream> 2 # ...

  7. BFS简单搜索--POJ 2243

    这题就是简单的BFS搜索,刚刚转到C++,还有很多库函数不熟悉,理解到BFS是一种奇妙的迭代法,其用的主要是队列的性质. 1 /*BFS简单搜索*/ 2 #include<iostream> ...

  8. (BFS)Knight Moves(hdu1372)

    题目: 在象棋王国,尼古拉斯.火山是一匹英俊的马,他非常幸运迎娶了白马王国的公主,他们将度蜜月,你现在是他们的女仆,火山会问你去一些地方最少需要多少步,这么简单的事当然难不倒你.由于火山是一匹马,他的 ...

  9. 吴昊品游戏核心算法 Round 9 —— 黑白棋AI系列之西洋跳棋(第二弹)(双向BFS+STL)(POJ 1198)...

    接上回,如图所示,这是黑白棋的一个变种,Solitaire也是一种在智能手机上普遍存在的一种游戏.和翻转棋(Flip Game)一样,西洋跳棋(Solitaire)也没有正统的黑白棋(奥赛罗,又称Ot ...

最新文章

  1. 使用DataGrid动态绑定DropDownList
  2. WebBrowser控件参数解释
  3. 运维笔记--postgresql占用CPU问题定位
  4. java get post 区别详解_[Java教程]GET 与 POST 其实没有什么区别
  5. 笔记-项目立项管理-项目论证的程序
  6. 计算机网络 --- 传输层TCP协议
  7. jy61 树莓派_用Linux树莓派来读取JY61的串口数据
  8. matlab mex gcc 支持c99
  9. windows station和desktop
  10. c语言求5个整数最小公倍数,C语言求两个正整数的最小公倍数和最大公约数
  11. 安装软件时提示“系统管理员设置策略禁止此安装”,解决方案
  12. hadoop 8088端口网页无法打开的原因分析
  13. 数据分析师培训告诉你 三个最常见的数据分析面试方向
  14. 看微软IE7.0更新的一家之言(转)
  15. multi_map_server/MultiOccupancyGrid.h:没有那个文件或目录
  16. 计算机专业国外访学进修目的,浙江师范大学关于2012年度专业技术职务评审工作的实施意见...
  17. 2019级C语言大作业 - 泡泡龙
  18. Android微信智能心跳方案(转)
  19. 读书笔记 第四章 创造力
  20. 关于脱发掉发,你应该知道的小知识。

热门文章

  1. python100例详解-Python编程之属性和方法实例详解
  2. java hash简易_Java手写简易版HashMap的使用(存储+查找)
  3. 远程修改服务器登录密码,远程服务器修改登录密码
  4. 封装echarts 柱状图和曲线
  5. java jshelllink_02--Java Jshell的使用 最适合入门的Java教程
  6. nmon安装为什么重启mysql_Centos7部署nmon监控工具
  7. 【模拟】牛客网:区间表达
  8. 小试ImageMagik——使用篇
  9. 视频帧率对人眼主观感受的影响 2
  10. 视频编码国家标准AVS与H.264的比较(节选)