POJ 1915 Knight Moves
POJ 1915 Knight Moves
| Time Limit: 1000MS | Memory Limit: 30000K | |
| Total Submissions: 29912 | Accepted: 14058 |
Description
Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else
but him can move knights from one position to another so fast. Can you
beat him?
The Problem
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.
Input
Next follow n scenarios. Each scenario consists of three lines
containing integer numbers. The first line specifies the length l of a
side of the chess board (4 <= l <= 300). The entire board has size
l * l. The second and third line contain pair of integers {0, ...,
l-1}*{0, ..., l-1} specifying the starting and ending position of the
knight on the board. The integers are separated by a single blank. You
can assume that the positions are valid positions on the chess board of
that scenario.
Output
each scenario of the input you have to calculate the minimal amount of
knight moves which are necessary to move from the starting point to the
ending point. If starting point and ending point are equal,distance is
zero. The distance must be written on a single line.
Sample Input
3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1
Sample Output
5
28
0
Source
TUD Programming Contest 2001, Darmstadt, Germany
这题算是比较简单的BFS了,但数据较大,普通的BFS会超时,但用双向BFS就没有这个问题。
双向BFS
双向BFS的原理是起点和终点同时扩展节点,当遇到相同的节点时,记录答案退出。双向BFS减少了节点的扩展,效率比普通的BFS高出几倍,且内存开销小,是NOIP必备的技能。
code
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std; int read()
{
int x=0,f=1;char c=getchar();
while (c<'0' || c>'9'){if (c=='-')f=-1;c=getchar();}
while (c>='0'&&c<='9'){x=(x<<1)+(x<<3)+c-48;c=getchar();}
return x*f;
} const int MAXN=310;
const int dx[]={0,1,1,-1,-1,2,2,-2,-2};
const int dy[]={0,2,-2,2,-2,1,-1,1,-1};
int n,ans;
bool flag; struct dot
{
int x,y,step;
void in()
{
x=read();y=read();
step=0;
} bool operator == (struct dot tmp)
{
if (x==tmp.x && y==tmp.y)return true;
return false;
}
}Start,End;
int step[MAXN][MAXN];
bool vis[2][MAXN][MAXN];
queue<dot> Q[2]; bool ok(int x,int y)
{
if (x<0 || x>=n)return false;
if (y<0 || y>=n)return false;
return true;
} void get_next(int z)
{
struct dot top,tmp;
top=Q[z].front();Q[z].pop();
for (int i=1;i<=8;i++)
{
tmp.step=top.step+1;
tmp.x=top.x+dx[i];
tmp.y=top.y+dy[i];
if (!ok(tmp.x,tmp.y))continue;
if (vis[1-z][tmp.x][tmp.y])
{
ans=tmp.step+step[tmp.x][tmp.y];
flag=true;
return ;
}
if (!vis[z][tmp.x][tmp.y])
{
vis[z][tmp.x][tmp.y]=true;
Q[z].push(tmp);
step[tmp.x][tmp.y]=tmp.step;
}
}
} void bfs()
{
while (!Q[0].empty())Q[0].pop();
while (!Q[1].empty())Q[1].pop();
Q[0].push(Start);Q[1].push(End);
while (!Q[0].empty()||!Q[1].empty())
{
if (Q[0].front()==End)
{
ans=Q[0].front().step;
return ;
}
if (!Q[0].empty()&&Q[0].size()<Q[1].size())get_next(0);
else get_next(1);
if (flag)return ;
}
} int main()
{
int cas;cas=read();
while (cas--)
{
flag=0;
memset(step,0,sizeof(step));
memset(vis,0,sizeof(vis));
n=read();
Start.in();End.in();
vis[0][Start.x][Start.y]=1;
vis[1][End.x][End.y]=1;
bfs();
printf("%d\n",ans);
}
return 0;
}
双向BFS的优化
双向BFS效率是惊人的如果运用的好,效率将会更高
让我们来分析一下,当出现一边节点特别多时,扩展节点多的一边会使节点数成指数倍增长,最终导致效率退化到单向BFS,所以我的程序便用了一个if语句,使两个BFS中的节点尽量平衡。
PS:其实这题并不需要这样判断,数据规模和节点的扩展都使得两边会差不多平衡。但这也不失是一种好的优化技巧。
点个赞吧
POJ 1915 Knight Moves的更多相关文章
- OpenJudge/Poj 1915 Knight Moves
1.链接地址: http://bailian.openjudge.cn/practice/1915 http://poj.org/problem?id=1915 2.题目: 总Time Limit: ...
- POJ 1915 Knight Moves(BFS+STL)
Knight Moves Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 20913 Accepted: 9702 ...
- POJ 2243 Knight Moves(BFS)
POJ 2243 Knight Moves A friend of you is doing research on the Traveling Knight Problem (TKP) where ...
- POJ 2243 Knight Moves
Knight Moves Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13222 Accepted: 7418 Des ...
- 【POJ 2243】Knight Moves
题 Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are ...
- POJ Knight Moves 2243 x
Knight Moves Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13974 Accepted: 7797 Des ...
- POJ---2243 Knight Moves 使用A*算法的广度优先搜索
题目链接:http://poj.org/problem?id=2243 启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标.这样可以省 ...
- poj2243 Knight Moves(BFS)
题目链接 http://poj.org/problem?id=2243 题意 输入8*8国际象棋棋盘上的两颗棋子(a~h表示列,1~8表示行),求马从一颗棋子跳到另一颗棋子需要的最短路径. 思路 使用 ...
- POJ2243 Knight Moves —— A*算法
题目链接:http://poj.org/problem?id=2243 Knight Moves Time Limit: 1000MS Memory Limit: 65536K Total Sub ...
随机推荐
- 《HelloGitHub》第 30 期
公告 截止到第 30 期,贡献者 终于到达 3 位数-- 100 位.谢谢各位的支持和贡献,想要加入的小伙伴,快来推荐项目吧! <HelloGitHub>第 30 期 兴趣是最好的老师,H ...
- springboot~thymeleaf页面布局的步骤
参考:https://ultraq.github.io/thymeleaf-layout-dialect/Installation.html 依赖包 注意里面的thymeleaf-layout-dia ...
- 数据结构系列(4)之 B 树
本文将主要讲述另一种树形结构,B 树:B 树是一种多路平衡查找树,但是可以将其理解为是由二叉查找树合并而来:它主要用于在不同存储介质之间查找数据的时候,减少 I/O 次数(因为一次读一个节点,可以读取 ...
- List去重的实现
List<T> 当T为值类型的时候 去重比较简单,当T为引用类型时,一般根据业务需要,根据T的中几个属性来确定是否重复,从而去重. 查看System.Linq下的Enumerable存在一 ...
- webservice创建、部署和调用
webservice 可以用于分布式应用程序之间的交互,和不同程序之间的交互. 下面通过一个简单的例子来创建一个webservice,用的是vs2010开发工具 首先创建一个web应用程序 接着我们添 ...
- 解决OracleOraDb10g_home1TNSListener服务无法启动
造成OracleOraDb10g_home1TNSListener服务无法启动可能有三种情况: listener.ora文件配置有错误导致无法启动 相关环境变量没设置好 删除客户端时导致服务端相关注册 ...
- error C1189: #error : Building MFC application with /MD[d] (CRT dll version) requires MFC shared dll version. Please #define _AFXDLL or do not use /MD[d]
今天在开发过程中遇到了C1189 error.找了好久解决办法,最后自己解决了...... 方法:工程右键->属性 编辑预处理器定义: 再次运行,就解决了.
- Python安装第三方包(模块/工具)出现链接超时,网速慢,安装不上的问题如何解决
之前我的电脑重新装了系统以后,发现安装完Python后, 使用pip linstall 安装第三方包的时候,网速慢的一匹 有时候只有几百b/s ,而且还动不动就会出现无法安装,链接超时等问题. 今天我 ...
- Simulink 产品说明
Simulink 产品说明 仿真和基于模型的设计 Simulink® 是一个模块图环境,用于多域仿真以及基于模型的设计.它支持系统级设计.仿真.自动代码生成以及嵌入式系统的连续测试和验证.Simuli ...
- 测者的测试技术手册:Junit单元测试遇见的一个枚举类型的坑(枚举类型详解)
Enum的简介 枚举类型很早就在计算机语言中存在了,主要被用来将一组相似的值包含进一种类型中,这种类型的名称被定义成独一无二的类型描述符,这就是枚举类型. 在java语言中,枚举类型是一个完整功能的类 ...
