Description

吃豆人是一款非常经典的游戏,游戏中玩家控制吃豆人在地图上吃光所有豆子,并且避免被怪物抓住。

这道题没有怪物,将游戏的画面分成n*m的格子,每格地形可能为空地或者障碍物,吃豆人可以在空地上移动,吃豆人每移动一格需要1s时间,并且只能朝上下左右四个方向移动,特别的是吃豆人还能吐出舌头,舌头每移动一格需要0.1s时间,舌头只可以走直线。不必考虑吃豆人转身所需要的时间。

举例,吃豆人在(1,1)坐标,而豆子在(1,5)坐标,并且中间没有障碍物,此时朝豆子方向吐舌头~,经过0.8s就可以吃到豆子(来回各0.4s,吐出去的舌头要缩回来的嘛)。

游戏中还有加速道具,一旦得到加速道具,吃豆人就获得2倍移动速度,吐舌头的速度没有增加,即走1格用0.5s。现在地图上有且只有一颗豆子。游戏中有.代表空地;X表示障碍,吃豆人不能越过障碍;B代表豆子;S代表加速道具,并且地图上道具总数不超过1个,道具所在的位置为空地,得到道具后立即使用,道具立即消失,地形变为空地,不能用舌头去取道具;P表示吃豆人,吐舌头的时候吃豆人不能移动。

Input

输入包含多组数据。输入第一行有两个个整数n,m(2<=n,m<=20),接着一个n*m的地图矩阵。

对于50%的数据,地图上没有道具。

Output

输出一行,最快用多少s吃到豆子,结果保留1位小数,如果吃不到,输出-1。

Sample Input

2 2
XP
B.
3 2
XP .
S B.

Sample Output

1.2
1.7
 
思路:舌头是不能越过障碍的。由于道具最多只有一个,我们分两种情况,一是不拿道具,那么可先BFS出起点到各个点的最短距离,然后再枚举每个可以走到的位置,判断在该位置吐舌头能否得到更优解。二是从起点去拿道具,然后从道具那个位置出发,也BFS出道具到每个点的最短距离,考虑到达每个位置吐舌头能否得到更优解
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int INF = 0x3f3f3f3f;
int n, m;
char mat[][]; int px, py, bx, by, sx, sy; struct node {
int x, y;
node() {}
node(int x, int y) : x(x), y(y) {}
};
queue<node> que;
int dir[][] = { {, }, {, }, {, -}, {-, } };
int md[][][], vis[][];
void init() {
memset(md, INF, sizeof md);
sx = sy = -;
for(int i = ; i < n; ++i)
for(int j = ; j < m; ++j) {
if(mat[i][j] == 'P') px = i, py = j;
if(mat[i][j] == 'B') bx = i, by = j;
if(mat[i][j] == 'S') sx = i, sy = j;
}
}
bool check(int x, int y) {
if(x < || x >= n || y < || y >= m || vis[x][y] || mat[x][y] == 'X') return false;
return true;
}
void BFS(int x, int y, int f) {
while(!que.empty()) que.pop();
memset(vis, , sizeof vis);
vis[x][y] = ;
que.push(node(x, y));
md[f][x][y] = ;
node u, v;
while(!que.empty()) {
u = que.front();
que.pop();
for(int i = ; i < ; ++i)
{
v.x = u.x + dir[i][];
v.y = u.y + dir[i][];
if(check(v.x, v.y)) {
que.push(v);
vis[v.x][v.y] = ;
md[f][v.x][v.y] = md[f][u.x][u.y] + ;
}
}
}
}
double ans; int to(int x, int y) {
if(bx == x) {
int y1 = min(by, y), y2 = max(by, y);
for(int i = y1 + ; i <= y2; ++i) if(mat[x][i] == 'X') return -;
return y2 - y1;
}else if(by == y) {
int x1 = min(bx, x), x2 = max(bx, x);
for(int i = x1 + ; i <= x2; ++i) if(mat[i][y] == 'X') return -;
return x2 - x1;
}
return -;
}
void solve1() {
for(int i = ; i < n; ++i) {
for(int j = ; j < m; ++j) if(md[][i][j] != INF) {
int dis = to(i, j);
if(dis == -) continue;
ans = min(ans, md[][i][j] + (double)dis * 0.1 * );
}
}
}
void solve2() {
int res = md[][sx][sy];
if(res == INF) return;
for(int i = ; i < n; ++i) {
for(int j = ; j < m; ++j) if(md[][i][j] != INF) {
int dis = to(i, j);
ans = min(ans, res + md[][bx][by] / 2.0);
if(dis != -) ans = min(ans, res + md[][i][j] / 2.0 + (double)dis * 0.1 * );
}
}
}
int main() {
//freopen("in", "r", stdin);
while(~scanf("%d%d", &n, &m)) {
for(int i = ; i < n; ++i) scanf("%s", mat[i]);
init();
BFS(px, py, );
if(sx != -)
BFS(sx, sy, ); ans = INF;
if(md[][bx][by] == INF) { puts("-1"); continue; }
solve1();
if(sx != -)
solve2();
printf("%.1f\n", ans);
}
return ;
}

Fzu2124 - 吃豆人 BFS的更多相关文章

  1. FZU 2124 吃豆人 bfs

    题目链接:吃豆人 比赛的时候写的bfs,纠结要不要有vis数组设置已被访问,没有的话死循环,有的话就不一定是最优解了.[此时先到的不一定就是时间最短的.]于是换dfs,WA. 赛后写了个炒鸡聪明的df ...

  2. FZU 2124 FOJ 2124 吃豆人【BFS】

     Problem 2124 吃豆人 Accept: 134    Submit: 575 Time Limit: 1000 mSec    Memory Limit : 32768 KB  Probl ...

  3. TurnipBit开发板DIY呼吸的吃豆人教程实例

    转载请以链接形式注明文章来源(MicroPythonQQ技术交流群:157816561,公众号:MicroPython玩家汇) 0x00前言 吃豆人是耳熟能详的可爱形象,如今我们的TurnipBit也 ...

  4. [代码]解析nodejs的require,吃豆人的故事

    最近在项目中需要对nodejs的require关键字做解析,并且替换require里的路径.一开始我希望nodejs既然作为脚本语言,内核提供一个官方的parser库应该是一个稳定可靠又灵活的渠道,然 ...

  5. Unity项目 - 吃豆人Pacman

    项目展示 Github项目地址:Pacman 涉及知识 切片制作 Animations 状态机设置,any state切换,重写状态机 按键读取进行整数距离的刚体移动 用射线检测碰撞性 渲染顺序问题 ...

  6. 利用纯css写三角形,弧度箭头,吃豆人,气泡。放大镜,标签的源码

    1. 向上三角形

  7. css吃豆人动画

    一. Css吃豆人动画 1. 上半圆:两个div,内部一个圆div,外部设置宽高截取半圆 外部div动画:animation: 动画样式 1s(时长) ease(动画先低速后快速) infinite( ...

  8. 用python的turtle作图(二)动画吃豆人

    本文是用python的turtle作图的第二篇,通过这个例子可以了解动画的原理,用python自带的turtle库制作一些小动画. 1.问题描述 在上一篇"用python的turtle作图( ...

  9. Pac-Man 吃豆人

    发售年份 1980 平台 街机 开发商 南梦宫(Namco) 类型 迷宫 https://www.youtube.com/watch?v=dScq4P5gn4A

随机推荐

  1. iOS-不用网线搭建IPv6网络测试环境

    前言 从6月1日开始苹果要求之后审核的项目必须支持iPv6,如果不支持将被拒绝,掘金最近一次审核被就被拒绝了....理由为下: Apps are reviewed on an IPv6 network ...

  2. 深入浅出HTTP请求(转自http://www.cnblogs.com/yin-jingyu/archive/2011/08/01/2123548.html)

    HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则.计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器(Web服务 器)请 ...

  3. Win7如何删除需要管理员权限才能删除的文件夹

    在Windows 7系统运行中.往往会遇到想要删除某个文件夹时,系统提示:文件夹访问被拒绝 你需要权限来执行此操作,如何才能删除此类文件夹呢? ------------------ --------- ...

  4. MAC地址是什么

    简介: MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址.硬件地址,用来定义网络设备的位置.在OSI模型中,第三 ...

  5. __index

    Window = {} Window.prototype = {x = , y = , width = , height = } Window.mt = {} function Window.new( ...

  6. ExtJs 实现表单联动

    最近做的项目使用Extjs.遇到表单联动的业务.下面来说说主要实现思想: 说明:表单联动一般存在从属关系,有大范围的对象和大范围中的小对象.比如地理位置的选定(例:浙江省-杭州市-某某县).在这里,我 ...

  7. [NHibernate]视图处理

    目录 写在前面 文档与系列文章 视图 一个例子 总结 写在前面 前面的文章主要讲了对物理数据表的操作,当然了Nhibernate同样可以操作视图,本文将讲nhibernate对视图操作的种种. 文档与 ...

  8. 莫比乌斯环-vtkTriangleStrip

    #ifndef INITIAL_OPENGL #define INITIAL_OPENGL #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRend ...

  9. 【荐】PHP操作MongoDB GridFS 存储文件,如图片文件

    GridFS是MongoDB的一个内置功能,它提供一组文件操作的API以利用MongoDB存储文件,GridFS的基本原理是将文件保存在两个Collection中,一个保存文件索引,一个保存文件内容, ...

  10. 如何在网页中嵌套其他的HTML文件

    html文件引入其它html文件的方法有三种,具体可以看下:1.IFrame引入,看看下面的代码 <IFRAME NAME="content_frame" width=100 ...