POJ 1915 Knight Moves

                      Knight Moves
 
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 29912   Accepted: 14058

Description

Background
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

The input begins with the number n of scenarios on a single line by itself.

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

For
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的更多相关文章

  1. OpenJudge/Poj 1915 Knight Moves

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

  2. POJ 1915 Knight Moves(BFS+STL)

     Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 20913   Accepted: 9702 ...

  3. POJ 2243 Knight Moves(BFS)

    POJ 2243 Knight Moves A friend of you is doing research on the Traveling Knight Problem (TKP) where ...

  4. POJ 2243 Knight Moves

    Knight Moves Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13222   Accepted: 7418 Des ...

  5. 【POJ 2243】Knight Moves

    题 Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are ...

  6. POJ Knight Moves 2243 x

    Knight Moves Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13974   Accepted: 7797 Des ...

  7. POJ---2243 Knight Moves 使用A*算法的广度优先搜索

    题目链接:http://poj.org/problem?id=2243 启发式搜索:启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标.这样可以省 ...

  8. poj2243 Knight Moves(BFS)

    题目链接 http://poj.org/problem?id=2243 题意 输入8*8国际象棋棋盘上的两颗棋子(a~h表示列,1~8表示行),求马从一颗棋子跳到另一颗棋子需要的最短路径. 思路 使用 ...

  9. POJ2243 Knight Moves —— A*算法

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

随机推荐

  1. jquery快速入门(二)

    jQuery 效果 1.隐藏,显示 1.1显示 hide() 和隐藏 show() 语法:$(selector).hide(speed,callback); $(selector).show(spee ...

  2. 取之有道——巧用Root权限 启动其他APP中的Activity

    这次博主来分享一个很巧妙的办法来启动其他APP中Activity的方法. 首先说一下这样做的目的:最近博主在攻克一个技术难点,就是搞定某些三方系统中,对于应用权限的限制.为此给出用户指导,引导用户启动 ...

  3. [PHP] MIME邮件协议的multipart类型

    邮件协议中的三种情况,对应下面的三种类型 multipart/mixed可以包含附件.multipart/related可以包含内嵌资源.multipart/alternative 纯文本与超文本共存 ...

  4. Java虚拟机判定对象存活算法

    1.引用计数算法 描述:给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器值为0的对象就是不可能再被使用的. 特点:实现简单,判定效率高. ...

  5. linux下载服务器上的文件命令-sz

    语法:sz  文件 比如要下载下面这个com.zip这个压缩包 输入sz com.zip 弹出下载页面,即可开始下载文件

  6. 初学Linux要掌握的命令

    echo:打印,或者直接输出指定的字符串 语法:echo (选项) (参数) 选项:/a: 发出警告声 /b: 删除前一个字符 /c: 最后不加上换行符号 /f: 换行但光标仍旧停留在原来的位置 /n ...

  7. 利用Redis keyspace notification(键空间通知)实现过期提醒

    一.序言: 本文所说的定时任务或者说计划任务并不是很多人想象中的那样,比如说每天凌晨三点自动运行起来跑一个脚本.这种都已经烂大街了,随便一个 Crontab 就能搞定了. 这里所说的定时任务可以说是计 ...

  8. 关于HTTPS的简要内容

    HTTPS是什么? 超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为HTTP over TLS,HTTP over SSL或HT ...

  9. AFO && OI回忆录

    技不如人,甘拜下风 今天是2019.4.6,联考第一天,菜鸡attack原题爆炸(其实是都不会)心灰意冷(其实并没有很难过)写下了这篇文章 T1 2h写个跟\(k\)无关的假算法写到最后发现是三个lo ...

  10. [C#学习笔记1]用csc.exe和记事本写一个C#应用程序

    csc.exe是C#的命令行编译器(CSharpCompiler),可以编译C#源程序成可执行程序.它与Visual Studio等IDE(Integrated Development Environ ...