Aizu 0558

Aizu 0558

BFS

题意

有一只老鼠从起点开始,每次向周围四个方向移动,每次移动的代价是单位\(1\),图上有\(k\) 个奶酪,每个奶酪有自己的价值\(A_i\) 老鼠每次只能吃到小于等于他能力值的奶酪,奶酪的价值范围是\(0\sim9\) ,老鼠的初始能力为\(1\)

求老鼠吃完所有奶酪所需要的最短时间

思路

因为老鼠不能吃到大于自己能力值的奶酪,所以他只能从小到大吃,每次只能吃一个奶酪

所以我们可以把这个求最短路的过程分解为\(Start-A_1\) ,\(A_1-A_2\),\(A_{k-1}-A_k\)

对于每一步,分别来求最短路,即把整个过程分解成小的一部分,然后再把总时间加起来即可

这样就不用考虑搜索过程中的等级问题,路径规划问题等,是一个很巧妙的思路

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define endl '\n'
const int N = 1e3 + 10,INF = 0x3f3f3f3f;
char g[N][N];
int gx[N],gy[N],dist[N][N];
int dx[4] = {0,0,1,-1},dy[4] = {1,-1,0,0};
int n,m,k,ans;
struct node {
    int x,y;
};
bool check(int x,int y) {
    return x >= 0 && x < n && y >= 0 && y < m && g[x][y] != 'X';
}
int bfs(int x,int y,int endx,int endy) {
    queue<node> q;
    memset(dist,0x3f,sizeof dist);
    q.push({x,y});
    dist[x][y] = 0;
    while(q.size()) {
        node t = q.front();
        q.pop();
        if(t.x == endx && t.y == endy) break;
        for(int i = 0;i < 4; ++i) {
            int nx = t.x + dx[i],ny = t.y + dy[i];
            if(check(nx,ny) && dist[nx][ny] == INF) {
                q.push({nx,ny});
                dist[nx][ny] = dist[t.x][t.y] + 1;
            }
        }
    }
    return dist[endx][endy];
}
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin >> n >> m >> k;
    for(int i = 0;i < n; ++i) {
        for(int j = 0;j < m; ++j) {
            cin >> g[i][j];
            if(g[i][j] == 'S') gx[0] = i,gy[0] = j;
            if(g[i][j] >= '1' && g[i][j] <= '9') {
                int start = g[i][j] - '0';
                gx[start] = i;
                gy[start] = j;
            }
        }
    }
    for(int i = 0;i < k; ++i) {
        ans += bfs(gx[i],gy[i],gx[i + 1],gy[i + 1]);
    }
    cout << ans << endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/lukelmouse/p/12441443.html