思路:一开始以为是一道DFS,也很快就写好代码,发现编译后结果错误。发现题目给的第一组数据就不行了,又看了一下,发现我的代码不能实现最优路径,于是又自作聪明地将走过的路径标记掉,又运行了一下,发现第三组数据又不行了,原来我的代码在这组数据就不行了,这样才发现并不是标记掉就行的,有些数据不标记掉能够成功走出,反而标记掉就不能走出来。这时,就要判断了。想了一会,觉得应该用BFS。不过BFS一般要标记走过的点。顿时没了思路。最后,纠结地在网上查了资料。原来确实可以用BFS,只不过这里就不要标记了。只需判断,前一步走过的点,后来又走了一遍,显然后来走的时间耗费要比前面的多,这时就要考虑二个时刻的炸弹剩余爆炸时间。如果后面大于前面的。就表明后面的点可以扩展。最后,总结:自己对搜索毕竟还很不熟悉,且对其的变化知之甚微。自己应加强对搜索题的灵敏度,这样对各种变化就能够知道所以然了。
代码如下:#include <iostream>
#include <queue>
using namespace std;
int str[9][9],dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int time[9][9];
int N,M;
int si,sj,ei,ej,flag;
typedef struct
{
int x,y;
int pasttime,lefttime;
}point;
void bfs()
{
point p1,p2;
int i,j;
queue<point> q;
p1.x=si;
p1.y=sj;
p1.pasttime=0;
p1.lefttime=6;
for(i=0;i<9;i++)
for(j=0;j<9;j++)
time[i][j]=0;
time[p1.x][p1.y]=6;
q.push(p1);
while(!q.empty())
{
p1=q.front();
q.pop();
for(i=0;i<4;i++)
{
p2.x=p1.x+dir[i][0];
p2.y=p1.y+dir[i][1];
p2.lefttime=p1.lefttime;
p2.pasttime=p1.pasttime;
if(p2.x>=0&&p2.x<N&&p2.y>=0&&p2.y<M&&str[p2.x][p2.y]!=0)
{
p2.pasttime++;
p2.lefttime--;
if(p2.lefttime>0&&p2.x==ei&&p2.y==ej)
{
cout<<p2.pasttime<<endl;
flag=1;
return;
}
if(p2.lefttime>1&&str[p2.x][p2.y]==1)
{
if(p2.lefttime>time[p2.x][p2.y])
{
time[p2.x][p2.y]=p2.lefttime;
q.push(p2);
}
}
else if(p2.lefttime>0&&str[p2.x][p2.y]==4)
{
p2.lefttime=6;
if(p2.lefttime>time[p2.x][p2.y])
{
time[p2.x][p2.y]=6;
q.push(p2);
}
}
}
}
}
if(!flag)
cout<<-1<<endl;
}
int main()
{
int i,j;
int num;
cin>>num;
while(num--)
{
cin>>N>>M;
for(i=0;i<N;i++)
for(j=0;j<M;j++)
{
cin>>str[i][j];
if(str[i][j]==2)
{
si=i;
sj=j;
}
if(str[i][j]==3)
{
ei=i;
ej=j;
}
}
flag=0;
bfs();
}
return 0;
}
3823257 | 2011-04-15 19:20:43 | Accepted | 1072 | 0MS | 276K | 1576 B | C++ |