Aizu--0558--迷宫好题思维

中文描述:

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值