逃离妖洞

描述

唐僧不小心又掉入妖怪的迷宫了。这个迷宫有n行m列,共n*m个方格。有的方格是空的,唐僧可以站在上面,有些是有障碍物的不能站。每次唐僧可以移动到相邻的8个空方格上。但是有些情况不能移动,即从两个方格的缝隙中移动,如图:

为了逃出妖怪的洞穴,唐僧需要触发悟空在某个方格留下的宝物,宝物都是留在空的方格中的。如果唐僧站在某个留有宝物的方格中,那么这个宝物就会被触发。为了逃离妖洞,唐僧务必按顺序依次触发K个宝物,当最后一个宝物被触发后,唐僧将会逃离妖洞。

现在唐僧已经知道这个迷宫中的障碍方格和有宝物的方格情况,开始唐僧站在一个给定的方格。问他是否可以逃离妖洞?

输入
一共有T(T<=20)组测试数据。



每组含有行数n,列数m。(2<=n,m<=100)以及放有宝物的K(1<= K <=10)个方格。



下面n行,每行包含m个字符,用'.'表示空的方格,用'#'表示有障碍物的方格。



下面一行是起点位置(x,y),保证是空的方格。

下面的K行表示藏有宝物的空方格的位置,藏有宝物的方格是空的,没有障碍物。两个宝物不会放在同一个空方格中。需要按所给宝物顺序依次触发宝物。
输出
输出为了逃离妖洞,最少需要多少次移动。如果不能逃离,输出-1。
样例输入
3
3 3 2
...
...
...
1 1
1 3
2 2
3 3 1
...
.#.
...
1 1
3 3
2 3 1
..#
.#.
1 1
2 3
样例输出
3
3
-1

值得注意的地方

1.  宝物必须依次触发,也就是说不能提前通过未触发的宝物。

2. 起点可能位于某个宝物上面,如果不是位于第1个宝物的坐标,那么唐僧不可能逃离的。

AC代码:

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

const int maxn = 100 + 5;
int d[maxn][maxn];
char G[maxn][maxn];
int n, m, k;         

const int dx[] = {1,-1,0,0, 1,-1,-1,1};
const int dy[] = {0,0,1,-1, -1,-1,1,1};

struct node{
	int x, y;
	node(){
	}
	node(int x, int y):x(x), y(y){
	}
}h[15];

int bfs(int x, int y, char g){
	memset(d, -1, sizeof(d));
	queue<node>q;
	q.push(node(x, y));
	d[x][y] = 0;
	while(!q.empty()){
		node p = q.front();
		q.pop();
		x = p.x, y = p.y;
		if(G[x][y] == g) return d[x][y];
		for(int i = 0; i < 8; ++i){
			int px = x + dx[i], py = y + dy[i];
			if(px < 0 || px >= n || py < 0 || py >= m || G[px][py] == '#' || G[px][py] > g || d[px][py] != -1) continue;
			if(i >= 4 && G[x + dx[i]][y] == '#' && G[x][y + dy[i]] == '#') continue;
			q.push(node(px, py));
			d[px][py] = d[x][y] + 1;
		}
	}
	return -1;
}

int solve(int x, int y){
	if(G[x][y] == '#') return -1;
	if(G[x][y] != '.' && G[x][y] > '0') return -1;
	int ans = 0;
	for(int i = 0; i < k; ++i){
		int step = bfs(x, y, '0' + i);
		if(step == -1) return -1;
		ans += step;
		x = h[i].x, y = h[i].y;
	}
	return ans;
}

int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		scanf("%d%d%d", &n, &m, &k);
		for(int i = 0; i < n; ++i){
			scanf("%s", G[i]);
		}
		int x, y;
		scanf("%d%d", &x, &y);
		int x1, y1; //宝物的坐标
		for(int i = 0; i < k; ++i){
			scanf("%d%d", &x1, &y1);
			h[i] = node(x1 - 1, y1 - 1);
			G[x1 - 1][y1 - 1] = i + '0';
		}
		printf("%d\n",solve(x - 1, y - 1));
	}
	return 0;
}

如有不当之处欢迎指出!

nyoj1246 逃离妖洞 BFS的更多相关文章

  1. HDU 1728:逃离迷宫(BFS)

    http://acm.hdu.edu.cn/showproblem.php?pid=1728 逃离迷宫 Problem Description   给定一个m × n (m行, n列)的迷宫,迷宫中有 ...

  2. hdu1072 逃离迷宫系列 bfs

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1072/ 题意:逃离迷宫,路中可能有炸弹,总时间是6个单位,在有炸弹的位置,如果到达的时刻时间大于0,则恢复到6时 ...

  3. HDU 1728 逃离迷宫(BFS)

    Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有 ...

  4. [HIHO1328]逃离迷宫(bfs,位压)

    题目链接:http://hihocoder.com/problemset/problem/1328 这个题bfs到时候不止要存当前的坐标,还要存当前有哪几把钥匙.因为5把钥匙,所以可以直接用位来存,这 ...

  5. HDU 1728 逃离迷宫【BFS】

    题意:给出一个起点,一个终点,规定的转弯次数,问能否在规定的转弯次数内到达终点--- 这一题是学(看)习(题)的(解)@_@ 主要学了两个地方 一个是剪枝,如果搜到的当前点的转弯次数小于该点turn数 ...

  6. HDU 1728 逃离迷宫(DFS||BFS)

    逃离迷宫 Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可 ...

  7. 逃离迷宫(BFS)题解

    Problem Description 给定一个m × n (m行, n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有 ...

  8. 2018年长沙理工大学第十三届程序设计竞赛 G 逃离迷宫 【BFS】

    链接:https://www.nowcoder.com/acm/contest/96/G 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536 ...

  9. HDU - 1728 逃离迷宫 【BFS】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1728 思路 BFS 一开始 从开始位置 往四周走 如果能走的话 这个时候 转弯次数都是0 我们的标记不 ...

随机推荐

  1. Redis的部署

    笔者Q:972581034 交流群:605799367 欢迎加群交流 官方网站 redis.io 下载 cd /usr/local/src wget http://download.redis.io/ ...

  2. 理解javascript模块化(转)

    模块化是一个通用的编程最佳实践.程序的模块化使我们可以更方便地使用别人的代码,想要什么功能,就加载什么模块,从而提高代码的利用效率,增加开发速度. 模块就像积木,有了它,我们可以搭出各种各种功能样式的 ...

  3. 理解SSL/TLS协议

    理解SSL/TLS协议 背景 早期我们在访问web时使用HTTP协议,该协议在传输数据时使用明文传输,明文传输带来了以下风险: 1.信息窃听风险,第三方可以获取通信内容 2.信息篡改风险,第三方可以篡 ...

  4. Web安全之CSP

    内容安全策略(Content-Security-Policy,简称CSP) 概念: 内容安全策略(CSP)是一种web应用技术用于帮助缓解大部分类型的内容注入攻击,包括XSS攻击和数据注入等,这些攻击 ...

  5. springboot(十九):使用Spring Boot Actuator监控应用

    微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台的业务流会经过很多个微服务的处理和传递,出现了异常如何快速定位是哪个环节出现了问题? ...

  6. echarts中视觉映射器(visualMap)与时间轴(timeline)混用的实现方法

    1.简述 echarts中的 timeline 组件,提供了在多个 ECharts option 间进行切换.播放等操作的功能. 与其他组件些不同,它需要操作『多个option』. 所以除了基准的ba ...

  7. c#实现Word转换PNG图片

    由于项目需要,经过一些大神的指导以及github,stackOverflow找资料,写了个这么个程序. 主要是因为word文档有特殊字体,特殊字体处理就要用到EnhMetaFileBits,即获取一页 ...

  8. mongodb备份恢复,数据导入导出

    数据导出 mongoexport 假设库里有一张apachelog表,里面有2 条记录,我们要将它导出 /test/mongodb/bin/mongo use wxdata switched to d ...

  9. JVM学习(一)

    一.gc日志查看与分析 在sever端的run.xml中run和debug中加入如下参数: <jvmarg value="-XX:+PrintGCDateStamps"/&g ...

  10. BZOJ 1299: [LLH邀请赛]巧克力棒 [组合游戏]

    每次一人可以从盒子里取出若干条巧克力棒,或是将一根取出的巧克力棒吃掉正整数长度. Nim游戏多了一个决策:拿出一些石堆 显然只要给对方构造异或和为0的子集就行了 暴枚子集... #include &l ...