1450:【例 3】Knight Moves

 题解

这道题可以用双向宽度搜索优化(总介绍在  BFS 

给定了起始状态和结束状态,求最少步数,显然是用BFS,为了节省时间,选择双向BFS。

双向BFS,即从起点向终点搜,从终点向起点搜,扩展各自的状态,直到出现两者扩展的状态重合

优化:每次选择结点少的扩展

看一下骑士可以到达那些点呢??

所以当然要开两个队列啦

设定:

1. dis[ i ][ a ][ b ]:队列 i ,从起点(a,b)至少多少步

2.    v[ i ][ a ][ b ]:队列 i ,从起点(a,b)开始,标记是否走过

3.           q[ i ][ j ]:队列 i 中第 j 个元素

4.                 l[ i ]:队列 i 的头指针

5.                 r[ i ]:队列 i 的尾指针

代码

1.优化版 双向队列

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib> using namespace std; struct node
{
int x,y;
}q[][]; //定义两个队列
int text,ans,n,l[],r[];
int dis[][][],v[][][];
int dx[]={-,-,-,-,,,,}; //位移
int dy[]={-,,-,,-,,-,}; int expand(int k) //对队列 k 进行扩展
{
int t,i,j,x,y,d,tx,ty;
x=q[k][l[k]].x;
y=q[k][l[k]].y;
d=dis[k][x][y];
for(int i=;i<;i++) //八个方向扩展
{
tx=x+dx[i]; //新点
ty=y+dy[i]; if(tx>=&&tx<=n&&ty>=&&ty<=n&&!v[k][tx][ty]) //合法而且没走过
{
v[k][tx][ty]=; //标记走过
r[k]++; //入队
q[k][r[k]].x=tx;
q[k][r[k]].y=ty;
dis[k][tx][ty]=d+; //记录步数
if(v[-k][tx][ty])
//判断另一个队列中是否已经走过这个点,也就是判断是否重合相遇
//如果相遇,就找到了一条完整的最短路径
//k=0时,1-k=1
//k=1时,1-k=0
{
ans=dis[k][tx][ty]+dis[-k][tx][ty];
return ;
}
}
}
return ;
} void bfs()
{
if(q[][].x==q[][].x&&q[][].y==q[][].y) //起点终点本就相同
{
ans=; return;
}
v[][q[][].x][q[][].y]=; //标记走过
v[][q[][].x][q[][].y]=;
l[]=r[]=; //初始化头指针尾指针
l[]=r[]=;
while(l[]<=r[]&&l[]<=r[]) //两个队列都非空,先扩展结点数少的
{
if(r[]-l[]<r[]-l[])
{
if(expand()) return; //找到答案啦
l[]++; //QAQ 没找到,移动头指针继续找
}
if(r[]-l[]>=r[]-l[])
{
if(expand()) return;
l[]++;
}
} } int main()
{
scanf("%d",&text);
for(int i=;i<=text;i++) //多组数据
{
memset(dis,,sizeof(dis));
memset(v,,sizeof(v));
memset(q,,sizeof(q)); scanf("%d",&n); n=n-;
scanf("%d%d",&q[][].x,&q[][].y); //起点
scanf("%d%d",&q[][].x,&q[][].y); //终点
bfs();
printf("%d\n",ans);
} return ;
}

2.普通队列

(应该不是代码的锅吧,写着写着卡死一台电脑,换了一台就没事了)

#include<bits/stdc++.h>

using namespace std;

struct node
{
int x,y,step;
}s,e,now,next; int cnt,n,ans;
bool vis[][];
int dx[]={-,-,-,-,,,,};
int dy[]={-,,-,,-,,-,}; bool pan(int x,int y)
{
return x>=&&x<=n&&y>=&&y<=n&&!vis[x][y];
} int bfs()
{
queue<node>q;
s.step =;
q.push(s);
// vis[s.x ][s.y ]=1; //反正它还要被取出来
while(!q.empty())
{
now=q.front();
q.pop();
// vis[now.x ][now.y ]=0; //保证每个点都走一遍吧,不重复走点,不过要是加上的话,就超时了
if(now.x ==e.x &&now.y ==e.y ) //到达终点
{
return now.step ;
continue;
}
else
{
for(int i=;i<;i++)
{
next.x =now.x +dx[i];
next.y =now.y +dy[i];
if(pan(next.x ,next.y ))
{
next.step =now.step +;
q.push(next);
vis[next.x ][next.y ]=;
}
}
}
}
return ;
} int main()
{
scanf("%d",&cnt);
for(int i=;i<=cnt;i++)
{
memset(vis,,sizeof(vis)); scanf("%d",&n);
scanf("%d%d",&s.x ,&s.y );
scanf("%d%d",&e.x ,&e.y ); if(s.x ==e.x &&s.y ==e.y )
{
printf("0\n");
continue;
}
else
{
ans=bfs();
printf("%d\n",ans);
}
}
return ;
}

1450:【例 3】Knight Moves的更多相关文章

  1. HDU 1372 Knight Moves (bfs)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1372 Knight Moves Time Limit: 2000/1000 MS (Java/Othe ...

  2. HDU 1372 (搜索方向稍有改变) Knight Moves

    其实手写模拟一个队列也挺简单的,尤其是熟练以后. 尼玛,这题欺负我不懂国际象棋,后来百度了下,国际象棋里骑士的走法就是中国象棋里面的马 所以搜索就有八个方向 对了注意初始化标记数组的时候,不要把起点标 ...

  3. 917:Knight Moves

    题目链接:http://noi.openjudge.cn/ch0205/917/ 原题应该是hdu 1372 总时间限制: 1000ms  内存限制: 65536kB 描述 BackgroundMr ...

  4. 【广搜】Knight Moves

    题目描述 Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights fr ...

  5. 跳马(Knight Moves), ZOJ1091, POJ2243 x

    跳马(Knight Moves), ZOJ1091, POJ2243 题目描述: 给定象棋棋盘上两个位置 a 和 b,编写程序,计算马从位置 a 跳到位置 b 所需步数的最小值. 输入描述: 输入文件 ...

  6. Knight Moves (双向bfs)

    # 10028. 「一本通 1.4 例 3」Knight Moves [题目描述] 编写一个程序,计算一个骑士从棋盘上的一个格子到另一个格子所需的最小步数.骑士一步可以移动到的位置由下图给出. [算法 ...

  7. Knight Moves

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  8. HDU 1372 Knight Moves

    最近在学习广搜  这道题同样是一道简单广搜题=0= 题意:(百度复制粘贴0.0) 题意:给出骑士的骑士位置和目标位置,计算骑士要走多少步 思路:首先要做这道题必须要理解国际象棋中骑士的走法,国际象棋中 ...

  9. [宽度优先搜索] HDU 1372 Knight Moves

    Knight Moves Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tot ...

随机推荐

  1. layui ri laydate的常规使用,并且日期最大不能超过当前日期

    laydate的常规使用,分为两种方式实现日期组件 一.在 layui 模块中使用 下载layui   地址 :https://www.layui.com/  引入资源路径 js 和 css 通过下面 ...

  2. (一)老毛桃U盘启动盘制作

    制作U盘启动盘前,一定要将U盘数据进行备份.U盘启动盘制作步骤: 1. 到老毛桃官网上下载U盘制作程序http://www.laomaotao.org.cn/. 2. 双击运行安装包,设置安装路径. ...

  3. poj 1915 KnightMoves(bfs)

    Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24094   Accepted: 11364 De ...

  4. iotop发现jdb2/sdb1-8 io使用过高解决办法

    一.现象 [root@push-- ~]# iotop otal DISK READ: 0.00 B/s | Total DISK WRITE: 6.26 M/s TID PRIO USER DISK ...

  5. Codeforces 902 树同型构造 多项式长除法构造(辗转相除法)

    A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...

  6. [ZJOI2014]力 题解

    题目地址 洛谷P3338 Solution 第一道FFT的应用AC祭! 我们要求: \[E_j=\frac{F_j}{q_j}=\sum_{i<j}\frac{q_i}{(i-j)^2}-\su ...

  7. Rsync以守护进程(socket)的方式传输数据

    Rsync以守护进程(socket)的方式传输数据       Rsync服务部署 一.以守护进程(socket)的方式传输数据(重点) 部署环境: 分别用uname命令查看各系统相关信息   1 2 ...

  8. 那些jquery或javascript花招

    js定时器 定时器: 1)反复性定时器:格式:window.setInterval(“fn()”,1000); a)会反复执行 b)第二个参数是以毫秒计算的 2)一次性定时器:格式:window.se ...

  9. python之路day15--内置函数

    函数分为自定义函数和内置函数 python内置函数分类: 5.5.1 强制转换 int() / str() / bool() / list() / tuple() / dict() / set() 5 ...

  10. python接口自动化四(json数据处理)

    前言 有些post的请求参数是json格式的,这个前面第二篇post请求里面提到过,需要导入json模块处理. 一般常见的接口返回数据也是json格式的,我们在做判断时候,往往只需要提取其中几个关键的 ...