Biridian Forest(贪心,bfs,思维)

原题链接

题目描述

在这里插入图片描述
在这里插入图片描述

输入描述

在这里插入图片描述

输出描述

在这里插入图片描述

题目说明

在这里插入图片描述

输入样例1

5 7
000E0T3
T0TT0T0
010T0T0
2T0T0T0
0T0S000

输出样例1

3

输入样例2

1 4
SE23

输出样例2

2

题目大意: 在一片森林内存在你和其他竞争对手,你的目标是走到该森林的出口,但你的路线在其他竞争对手眼中是已知的(明牌! ),而其他竞争对手的目标是在路上偶遇你并和你打一架(不消耗时间),且每当你行动一格时,其他竞争对手也会行动一格,并且他们都很聪明不会选择绕路。求当你达到出口时所需要的最少的打架次数(即选中的某一路线上最少会遇到的其他竞争对手)。

标准阅读理解题,即使把原题生翻成中文后也很难直接看懂大意,因此不妨手模一下:

在这里插入图片描述

此处假设 A 为自己,B 为终点,在 A 到 B 的某一条线路上存在点 D,D 点为初始位置为 E 的敌人最早在该条线路上能与我们会合的位置。不难发现,在 D 点会合后敌人 E 完全可以与我们一起走完剩下的 DB 路段,而对于路程 DB + ED ,很显然可以得出该路程一定大于等于敌人直接从 E 走到终点 B 的距离 EB。因此对于能够在路中间的某点 D 上与我们会合的敌人,他也一定能够在终点 B 处等着我们 / 同时到达。由此可将本题转化为求当你到达终点时,同时或更早到达出口的人数。

由此本题可考虑 bfs 的思想,即从终点开始进行 bfs 搜索并标记每个方格到终点的最短路距离,并统计小于或等于自己到达终点的最短路距离的方格上的敌人数量。

参考代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010;

int n, m;
char g[N][N];
int dx[4] = {
    
    -1, 0, 1, 0}, dy[4] = {
    
    0, 1, 0, -1};
int dist[N][N];

int bfs(){
    
    
    memset(dist, 0x3f, sizeof dist);
    int sx, sy;
    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (g[i][j] == 'E')
                sx = i, sy = j;

    queue<PII> q;
    q.push({
    
    sx, sy});
    dist[sx][sy] = 0;

    while (q.size()){
    
    
        auto t = q.front();
        q.pop();

        for (int i = 0; i < 4; i ++ ){
    
    
            int x = t.x + dx[i], y = t.y + dy[i];
            if (x >= 0 && x < n && y >= 0 && y < m && g[x][y] != 'T')
                if (dist[x][y] > dist[t.x][t.y] + 1){
    
    
                    dist[x][y] = dist[t.x][t.y] + 1;
                    q.push({
    
    x, y});
                }
        }
    }

    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (g[i][j] == 'S')
                return dist[i][j];

    return -1;
}

int main(){
    
    
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);

    int t = bfs();
    int res = 0;

    for (int i = 0; i < n; i ++ )
        for (int j = 0; j < m; j ++ )
            if (g[i][j] > '0' && g[i][j] <= '9' && dist[i][j] <= t)
                res += g[i][j] - '0';
    printf("%d\n", res);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/laysan/article/details/120047374