AOJ 0558 Cheese
题意
有一只老鼠要吃奶酪,现在有n个奶酪,编号为1~n,小老鼠从起点要按顺序依次到达奶酪所在的点并吃掉,求最短所需步数。
细则:
- 只能上下左右走
- 必须要按1~n的顺序
- "S"为起点,"X"为阻挡物,"1~n"为第 i 个奶酪所在点
输入:第一行三个整数,分别为高h,宽w,奶酪个数。
输出:最小步数。
思路:写一个bfs求两点间最短路,然后依次换起点终点,详细看代码。
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int Maxn = 1000 + 10;
char mp[Maxn][Maxn];
int h, w, N;
int dir[][2] = {1, 0, -1, 0, 0, 1, 0, -1};//方向
int sx, sy, gx, gy;
typedef pair <int, int> P; //方便记录坐标
int d[Maxn][Maxn]; //用来记录每个点到起点的距离
int bfs(){
queue <P> que;
memset(d, INF, sizeof(d)); //初始化
que.push(P(sx, sy)); //push起点
d[sx][sy] = 0; //该点到起点距离为0
while(que.size()){
P p = que.front();
que.pop();
if(p.first == gx && p.second == gy) //到达终点,结束循环
break;
for(int i = 0; i < 4; i++){
int nx = p.first + dir[i][0];
int ny = p.second + dir[i][1];
if(nx >= 0 && nx < h && ny >= 0 && ny < w && mp[nx][ny] != 'X'//判断该点是否能走
&& d[nx][ny] == INF){ //还没走过的点
que.push(P(nx, ny));
d[nx][ny] = d[p.first][p.second] + 1;
}
}
}
return d[gx][gy];
}
P n[9]; //用于记录第 i 个奶酪的坐标
int main(){
cin >> h >> w >> N;
for(int i = 0; i < h; i++)
for(int j = 0; j < w; j++){
cin >> mp[i][j];
if(mp[i][j] == 'S'){ //记录起点坐标
sx = i;sy = j;
}
if(mp[i][j] <= '9' && mp[i][j] >= '1'){//奶酪坐标
n[mp[i][j] - '1'].first = i;
n[mp[i][j] - '1'].second = j;
}
}
int sum = 0;
for(int i = 0; i < N; i++){
gx = n[i].first;
gy = n[i].second;
sum += bfs();
sx = gx;sy = gy; //终点变起点
}
cout << sum << endl;
return 0;
}