题目大意:
在H * W的地图上有N个奶酪工厂,分别生产硬度为1-N的奶酪。有一只吃货老鼠准备从老鼠洞出发吃遍每一个工厂的奶酪。老鼠有一个体力值,初始时为1,每吃一个工厂的奶酪体力值增加1(每个工厂只能吃一次),且老鼠只能吃硬度不大于当前体力值的奶酪。
老鼠从当前格走到相邻的无障碍物的格(上下左右)需要时间1单位,有障碍物的格不能走。走到工厂上时即可吃到该工厂的奶酪,吃奶酪时间不计。问吃遍所有奶酪最少用时。
输入:第一行三个整数H(1 <= H <= 1000)、W(1 <= W <=1000)、N(1 <= N <= 9),之后H行W列为地图, “.“为空地, ”X“为障碍物,”S“为老鼠洞, 1-N代表硬度为1-N的奶酪的工厂。
此题依次吃奶酪即可。
先找到起点到奶酪1的最小步数,再以奶酪1为起点找到奶酪2的最小步数......最后把他们加起来即可。
此题还有个需要注意的是对于大于自己体力的奶酪所在的区域,不是不能过,而是能过,但是不能吃奶酪,过而不吃。
#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
char ma[1005][1005];
int vis[1005][1005];
int n,m,t,ax,ay,c;
struct node
{
int x,y,ti;//位置及时间
node(int a,int b,int c){x=a;y=b;ti=c;}
};
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
int bfs(int xx,int yy)
{
memset(vis,0,sizeof(vis));
queue<node> que;
que.push(node(xx,yy,0));
vis[xx][yy]=1;
while(!que.empty())
{
node tem=que.front();
que.pop();
//vis[tem.x][tem.y]=0;
for(int i=0;i<4;i++)
{
if(tem.x+dx[i]>=0&&tem.x+dx[i]<n&&tem.y+dy[i]>=0&&tem.y+dy[i]<m)//没越界
{
int x=tem.x+dx[i];
int y=tem.y+dy[i];
if(vis[x][y])continue;//如果这个点在经历过则换个方向
if(c==ma[x][y]-'0')//如果下一个是终点的话直接返回
{
ax=x;ay=y;
return tem.ti+1;
}
if(ma[x][y]=='X')continue;//如果是墙的话,那么只能换个方向
else//放入队列就好了
que.push(node(x,y,tem.ti+1));
vis[x][y]=1;
}
}
}
}
int main()
{
freopen("1.txt","r",stdin);
while(cin>>n>>m>>t)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
scanf("%s",&ma[i]);
for(int j=0;j<m;j++)
if(ma[i][j]=='S')
{
ax=i;ay=j;
}
}
int ans=0;
for(int i=1;i<=t;i++)
{
c=i;
ans+=bfs(ax,ay);
//cout<<ans<<endl;
}
cout<<ans<<endl;
}
}