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 ...
随机推荐
- Asp.Net Core 轻松学-玩转配置文件
前言 在 .NET Core 项目中,配置文件有着举足轻重的地位:与.NetFramework 不同的是,.NET Core 的配置文件都以 .json 结尾,这表示一个标准的 json 格式 ...
- JDK源码分析(2)之 Array 相关
在深入了解 Array 之前,一直以为 Array 比较简单,但是深入了解后才发现其实挺复杂的.所以我把重要的写在最前面,但凡遇到和语言本身相关的问题,都可以查阅 Java Language and ...
- linux-2.6.18源码分析笔记---中断
一.中断初始化 中断的一些硬件机制不做过多的描述,只介绍一些和linux实现比较贴近的机制,便于理解代码. 1.1 关于intel和linux几种门的简介 intel提供了4种门:系统门,中断门,陷阱 ...
- revit二次开发wpf里button按钮无法实现事务
不能在revit提供的api外部使用事务,解决此方法, 1.把button里要实现的功能写到外部事件IExternalEventHandler中,注册外部事件,在button事件中.raise()使用 ...
- Springboot整合activemq
今天呢心血来潮,也有很多以前的学弟问到我关于消息队列的一些问题,有个刚入门,有的有问题都来问我,那么今天来说说如何快速入门mq. 一.首先说下什么是消息队列? 1.消息队列是在消息的传输过程中保存消息 ...
- IntelliJ IDEA下如何设置JSP模板
今天在学习Spring MVC知识时,发现自己所用的IntelliJ IDEA中自动生成的JSP文件不支持EL表达式的使用,所以就想导入新的JSP模板,方便以后使用.根据旧模板的提示,如下图 找到Se ...
- 华为6.0系统设备最完美激活Xposed框架的经验
对于喜欢玩手机的伙伴而言,经常会使用上Xposed框架及种种功能强大的模块,对于5.0以下的系统版本,只要手机能获得root权限,安装和激活Xposed框架是非常轻松的,但随着系统版本的迭代,5.0以 ...
- OpenCV尝试
我们来尝试,使用OpenCV来读入本地的一张图片,并使用库函数将其水平翻转.垂直翻转以及边缘提取,后将结果文件存入本地. 工具:VS2017 OpenCV4.0.1 怎么配置opencv/报错怎么办 ...
- 路由刷rom手册
最近对家里面那5,6个路由器下手了. 路由列表:小米mini 2台. 优酷路由宝l1,tp wdr3320,tp wr840n, 友华wr1200js,小米路由r1n 步骤: 1. 想办法开启ssh ...
- jsp页面中include静态html出现乱码问题的解决方式
这个问题出现过两次,上次没有做好记录,今天又出现了.不过这两次的情景也不完全一致. 今天通过搜索找到这篇文章的解决方式很好,可供参考.原博客地址http://blog.csdn.net/izgnaw/ ...
