前一段时间一直在做dfs,今天开始做bfs,一开始就拜倒在这道题上了,题意就不解释了。感觉这道题也挺经典(当然是入门),以后要常拿出来看看。
思路:一定注意这道题是可以重复走的,刚开始没想到怎么处理这个问题,后来看了人家的解释才恍然大悟,不能只是做标记,而要看前一次走过的时间与这一次的大小关系,这次小则能走,大,则不能走。还有就是走后要的是总共走的时间,而不是调整炸弹后的时间,这个估计大部分人不会犯错,自己就犯二了。。。不过这道题的第一点又给自己开拓了思路。
代码如下:
#include<iostream>
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
int map[15][15];
int vis[15][15];
int sx,sy;
int dx[]= {0,0,1,-1};
int dy[]= {1,-1,0,0};
int n,m;
struct A
{
int x,y,tim;
int sumt;
};
bool bfs(int x,int y,int num)
{
queue<A> comb;
A a;
a.x=x;
a.y=y;
a.tim=num;
a.sumt=num;
comb.push(a);
while(!comb.empty())
{
a=comb.front();
comb.pop();
if(a.tim>=6)
continue;
if(map[a.x][a.y]==3)
{
cout<<a.sumt<<endl;
return true;
}
if(map[a.x][a.y]==4&&a.tim<=5)
{
a.tim=0;
}
A b;
for(int i=0; i<4; i++)
{
b.x=a.x+dx[i];
b.y=a.y+dy[i];
if(b.x>=1&&b.x<=n&&b.y>=1&&b.y<=m&&map[b.x][b.y]&&(a.tim+1<vis[b.x][b.y]))
{
b.tim=a.tim+1;
b.sumt=a.sumt+1;
comb.push(b);
vis[b.x][b.y]=b.tim;
}
}
}
return false;
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
memset(map,0,sizeof(map));
memset(vis,6,sizeof(vis));
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
{
cin>>map[i][j];
if(map[i][j]==2)
{
sx=i;
sy=j;
}
}
if(!bfs(sx,sy,0))
cout<<-1<<endl;
}
return 0;
}