中文描述:
在H * W的地图上有N个奶酪工厂,每个工厂分别生产硬度为1-N的奶酪。有一只老鼠准备从出发点吃遍每一个工厂的奶酪。老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次),且老鼠只能吃硬度不大于当前体力值的奶酪。 老鼠从当前格到上下左右相邻的无障碍物的格需要时间1单位,有障碍物的格不能走。走到工厂上时即可吃到该工厂的奶酪,吃奶酪时间不计。问吃遍所有奶酪最少用时
输入
第一行三个整数H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之后H行W列为地图, “.“为空地, ”X“为障碍物,”S“为老鼠洞,N表示有N个生产奶酪的工厂,硬度为1-N。
输出
输出一个整数,代表老鼠吃遍所有奶酪的最少时间花费。
输入样例1
3 3 1
S..
...
..1
输出样例1
4
输入样例2
4 5 2
.X..1
....X
.XX.S
.2.X.
输出样例2
12
输入样例3
10 10 9
.X...X.S.X
6..5X..X1X
...XXXX..X
X..9X...X.
8.X2X..X3X
...XX.X4..
XX....7X..
X..X..XX..
X...X.XX..
..X.......
输出样例3
91
思路:求S--->1---->2---->....---->n-1----->n的最短距离,显然是一道迷宫问题,可以用我写的模板;
模板:https://blog.csdn.net/queque_heiya/article/details/104086815
注意:1.不用考虑吃不完的情况(当时我有点懵逼);
2.找到(1---n)位置一定要更新当前的起始位置;
3.记录数组d[][]一定要在每次dfs之前初始化init();如果忘记了结果会偏小甚至错误;
//迷宫问题十分类似 bfs()才能达到目的
//需要改动的地方很多
//bfs最短路径好题,十分类似于图的最短路径处理方法
#include<queue>
#include<iostream>
using namespace std;
#include<algorithm>
const int INF=1e9;
const int MAX=1000+10;
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
//也可以考虑用二维方向数组解决
typedef pair<int,int> P;
char maze[MAX][MAX];
int N,M;
int sx,sy;//起点
int gx,gy;//终点
int d[MAX][MAX];//到各个位置最短距离的数组
void init(){//请读者思考,为什么在bfs()之前要初始化
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
d[i][j]=INF;
}
int bfs(){
queue<P>que;
que.push(P(sx,sy));
d[sx][sy]=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+dx[i],ny=p.second+dy[i];
//判断check
if(nx>=0&&ny>=0&&nx<N&&ny<M&&maze[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];
}
int main(){
int nn;//从1-2-3----nn依次计算;
cin>>N>>M>>nn;
for(int i=0;i<N;i++)
scanf("%s",maze[i]);
//找起点
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
if(maze[i][j]=='S'){
sx=i,sy=j;//起点之后会发生改变,尤其注意
}
else if(maze[i][j]>='1'&&maze[i][j]<='9')
maze[i][j]=maze[i][j]-'0';
int ans=0,cnt=1,flag=0;
//循环是一个向下的过程,而此题是一个空间内的任意任意变化
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
if(maze[i][j]==cnt){
init();
gx=i,gy=j;
ans+=bfs();
sx=gx,sy=gy;
//cout<<"------>>>>>>"<<ans<<endl;
cnt++;
i=0,j=0;
if(cnt==nn+1){
flag=1;
break;
}
}
}
if(flag)
break;
}
cout<<ans<<endl;
}