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;
}