2021-08-31 AcWing暑期最后一题 3825. 逃离大森林
你是一个宝可梦饲养员,你正在进行你的冒险之旅。
当前,你的目标是逃离飞鸟森林。
飞鸟森林可以表示为一个 r×c 的方格矩阵。
每个方格,要么是树木,要么是空地。
空地中可能包含 0 个或多个宝可梦饲养员(森林中可能存在除你以外的其他饲养员)。
所有饲养员(包括你在内)都不能进入到包含树木的方格之中。
有一个方格为出口方格,到达这里就可以逃离大森林。
出口方格一定是空地。
最初始的方格矩阵将提供给你,这包含了你的初始位置,出口方格的位置、空地和树木的分布以及其他所有饲养员的位置,
下图是一个初始方格矩阵的示例:
所有饲养员(包括你)都可以在森林中进行移动。
每次移动可以:
- 原地不动。也就是放弃本次移动。
- 沿上下左右四个方向移动一格距离。
注意,任何人都不可能移动至带有树木的方格中。
如果你在一次移动中,抵达了出口方格,那么下次移动你就可以选择离开森林。
其他饲养员不会以这种方式主动离开森林。
在你进行一次移动时,其他所有饲养员也会同时进行一次移动(每个饲养员的移动方式可能不尽相同)。
当你和 t个其他饲养员位于同一方格之中时,就会和他们进行 t 场一对一的战斗(战斗时间忽略不计)。
所有跟你战斗过的饲养员都会失去所有战斗力,无法再挑战你,只能饮恨离开森林。
注意,在你离开森林的那次移动中,即使有饲养员在此次移动中抵达出口方格,你也不会和他们发生战斗。
另外,其他饲养员只会和你发生战斗,其他饲养员之间不会发生战斗(可能有多个饲养员位于同一方格中)。
既然要离开森林,你就需要在开始行动之前制定一条行进路线,确定你的一系列移动。
在确定这个具体行动计划后,你一定会严格遵循制定好的路线开展你的所有移动。
并且你还会将你的行动路线提前公开发布到博客上。
其他所有饲养员都关注了你的博客,并且迫切的渴望与你战斗。
因为已经提前知道了你的所有移动顺序,所以其他饲养员当中,有机会在你的行进过程中碰到你的,都会主动撞上你,以确保能够和你战斗,而无论如何也碰不到你的,就会原地不动,不白费力气。
你是个不喜欢战斗的人,所以你想要制定一条最为合理的行进路线,使得你在逃离大森林的过程中进行战斗的场次尽可能少。
注意,为了达到这一目的,即使行进路线长于最短行进路线也在所不惜。
输入格式
第一行包含两个整数 r 和 c。
接下来 r 行,每行包含一个长度为 c 的字符串,表示森林矩阵。每个字符可能是:
T
:表示树木方格。S
:表示你的初始位置方格,这是一个空地,保证有且仅有一个。E
:表示出口方格,这是一个空地,保证有且仅有一个。- 一个数字(0∼9):表示空地方格,数字为 x 则表示该空地上有 x 个饲养员。
保证你一定可以从初始位置走到出口方格位置。
输出格式
输出一个整数,表示你最少需要进行的战斗场次。
数据范围
1≤r,c≤10001≤r,c≤1000
输入样例1:
5 7
000E0T3
T0TT0T0
010T0T0
2T0T0T0
0T0S000
输出样例1:
3
样例1解释
森林方格矩阵如下所示:
蓝色线路即为你可以选择的行进路线,在该行进路线中,只有左下方的三人可以撞到你,而右上角的三人无法撞到你,所以只需要进行三场战斗。
输入样例2:
1 4
SE23
输出样例2:
2
样例2解释
森林方格矩阵如下所示:
你在第一次移动中,直接移动至出口方格处:
与此同时,右边的两个人也移动至出口方格处,你们发生战斗(最右边的三人因为赶不上你,所以原地不动):
你把两个挑战者干跑了:
在第二次移动中,你选择离开森林:
思路:
竞争者都会接近你的逃跑路线,乃至稳合,那么如果他们可以在你逃出之前和你打架的话,他们到出口的最短路径一定小于等于你的最短路径
因此,问题转化为:找到那些和你同时到或者比你先到出口的人即可
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int, int> PII;//竞争者坐标
const int N = 1010;
int res=0;
int m,n,sx,sy;
int step[N][N];
char p[N][N];
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int bfs()
{
memset(step, 0x3f, sizeof step);
for (int i = 0; i < m; i ++ )
for (int j = 0; j < n; j ++ )
if (p[i][j] == 'E')
sx = i, sy = j;
queue<PII> q;
q.push({sx, sy});
step[sx][sy] = 0;
while (q.size())
{
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i ++ ){
int x = t.first + dx[i], y = t.second + dy[i];
if(x>=0 && x<m && y>=0 && y<n && p[x][y]!='T'){
if(step[x][y] > step[t.first][t.second]+1){
step[x][y] = step[t.first][t.second]+1;
q.push({x,y});
}
}
}
}
for (int i = 0; i < m; i ++ )
for (int j = 0; j < n; j ++ )
if (p[i][j] == 'S')
return step[i][j];
return -1;
}
int main()
{
cin >> m >> n;
for (int i = 0; i < m; i ++ ) scanf("%s", p[i]);
int res = 0;
int sum = bfs();
for (int i = 0; i < m; i ++ )
{
for (int j = 0; j < n; j ++ )
{
if(p[i][j]>'0' && p[i][j]<='9' && step[i][j]<=sum){
res += p[i][j]-'0';
}
}
}
cout << res;
return 0;
}
本文来自博客园,作者:泥烟,CSDN同名, 转载请注明原文链接:https://www.cnblogs.com/Knight02/p/15799116.html