题目描述
莘庄有很多酒吧,侯不会和苏前端打算约在其中一个酒吧见面。为了节省时间,他们希望从各自的家赶往酒吧的时间之和尽可能少,现在请你为他们挑选一个酒吧。莘庄可以被划分为 n × m n \times m n×m 个单元格,每个单元格可能是侯不会的家(‘H’)、苏前端的家(‘S’)、障碍物(’#’)、空地(’.’)或者酒吧(‘B’),其中障碍物所在位置不能通行,其余单元格均可通行,保证至少有一个酒吧两人都可以到达。侯不会和苏前端每分钟可以向上下左右移动一格。求侯不会和苏前端各自从家到酒吧的时间之和的最小值。
输入格式
第一行包含两个整数 n , m n, m n,m。( 2 ≤ n , m ≤ 1000 2 \le n, m \le 1000 2≤n,m≤1000)
接下来 n n n 行,每行有 m m m 个用空格隔开的字符。
'H’代表侯不会的家的位置。
'S’代表苏前端的家的位置。
'#'代表障碍物的位置。
'.'代表可通行的位置。
'B’代表酒吧的位置。
输出格式
一个整数,表示侯不会和苏前端各自从家到酒吧的时间之和的最小值。
样例输入
4 4
H.#B
....
.#..
B..S
样例输出
6
数据范围
对于 20 % 20\% 20%的数据, 2 ≤ n , m ≤ 20 2 \le n, m \le 20 2≤n,m≤20。
对于另外 20 % 20\% 20%的数据,地图上没有障碍物。
对于另外 20 % 20\% 20%的数据,地图上只有一个酒吧。
对于 100 % 100\% 100%的数据, 2 ≤ n , m ≤ 1000 2 \le n, m \le 1000 2≤n,m≤1000
题目解答
什么叫做水题?如果你做完了上一道题,那么这道题是实力水题!(新版)SJTU-OJ-1028.采购 传送门
什么?没有做过上一题?(新版)SJTU-OJ-1028.采购 传送门
什么?不会深度优先搜索?(新版)SJTU-OJ-1028.采购 传送门
这两个题目完全一样,都是途径一个点的问题,完全没有考的必要,做一道就可以,为了偷懒,我连上一道题目的shop都没有改,放AC代码!不解释,太简单了。只需要改#,H,B,S就可以。
// 所有坐标x代表行数,y代表列数!
// 本题坐标采用0-base!
// 这也太水了吧,就是之前那个国王题目,复制粘贴
// 伞店我都懒得吧shop改成bar,凑合看看就好
#include <iostream>
#include <queue>
#include <cstring>
#include <cmath>
using namespace std;
class shop
{
public:
int x;
int y;
};
class node
{
public:
int x;
int y;
}sh[1000000] = { 0,0 };
char testmap[1010][1010];
int step[1010][1010];
// 定义增量x,y 数组,
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
// 定义shop数组
int shopnum = 0;
int m, n;
bool bfs_CheckNextstep(node checkobject)
{
if (checkobject.x < 0 || checkobject.x >= n)
return false;
if (checkobject.y < 0 || checkobject.y >= m)
return false;
if (testmap[checkobject.x][checkobject.y] == '#')
return false;
if (step[checkobject.x][checkobject.y] != 0)
return false;
else
return true;
// if (nxt.x >= 0 && nxt.x < m && nxt.y >= 0 && nxt.y < n && step[nxt.x][nxt.y] == 0 && testmap[nxt.x][nxt.y] != 1)
// return true;
// else
// return false;
}
// 广度优先搜索,传入的时候传入一个节点node!
void bfs_Main(node departure)
{
memset(step, 0, sizeof(step));
// 首先定义一个队列!
queue<node> bfsque;
bfsque.push(departure);
node currentplace, nextplace;
while (!bfsque.empty())
{
currentplace = bfsque.front();
bfsque.pop(); // 把最前面的元素弹出去!
for (int i = 0; i < 4; i++)
{
nextplace.x = currentplace.x + dx[i];
nextplace.y = currentplace.y + dy[i];
if (bfs_CheckNextstep(nextplace) == true)
{
step[nextplace.x][nextplace.y] = step[currentplace.x][currentplace.y] + 1;
bfsque.push(nextplace);
}
}
}
}
int main()
{
cin >> n >> m;
node departure, destination;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
cin >> testmap[i][j];
if (testmap[i][j] == 'H')
{
departure.x = i;
departure.y = j;
}
if (testmap[i][j] == 'S')
{
destination.x = i;
destination.y = j;
}
if (testmap[i][j] == 'B')
{
sh[shopnum].x = i;
sh[shopnum].y = j;
shopnum++;
}
}
}
int a[10000] = {0};
int b[10000] = {0};
bfs_Main(departure);
for (int i = 0; i < shopnum; i++)
{
a[i] = step[sh[i].x][sh[i].y];
}
bfs_Main(destination);
for (int i = 0; i < shopnum; i++)
{
b[i] = step[sh[i].x][sh[i].y];
}
long int ans = 1e8;
long int temp;
for (int i = 0; i < shopnum; ++i)
{
if (a[i] > 0 && b[i] > 0)
{
temp = a[i] + b[i];
ans = min(ans, temp);
}
}
cout << ans;
system("pause");
return 0;
}