http://acm.hdu.edu.cn/showproblem.php?pid=1072
题目大意是在一个n×m的地图上,0表示墙,1表示空地,2表示人,3表示目的地,4表示有定时炸弹重启器。
定时炸弹的时间是6,人走一步所需要的时间是1。每次可以上、下、左、右移动一格。
当人走到4时如果炸弹的时间不是0,可以重新设定炸弹的时间为6。如果人走到3而炸弹的时间不为0时,
成功走出。求人从2走到3的最短时间。
一道典型的搜索,用的bfs,结构体中开一个step表示要求的时间,也就相当于步数,一个time表示炸弹的时间,
注意的是这里其实每个点都可以重复访问,为了求能够到达的最小时间,4的位置如果必须要走的话其实只走一次
一个炸弹点如果走多次,虽然设置了最大限时但是往返消耗了时间得不偿失,好好想想这里
code
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 using namespace std; 5 struct point { 6 int x,y; 7 int time,step;//炸弹时间与步数 8 }; 9 int dx[]={1,-1,0,0}; 10 int dy[]={0,0,1,-1}; 11 int n,m; 12 int visit[10][10],map[10][10]; 13 int bfs(int sx,int sy) 14 { 15 int i; 16 memset(visit,0,sizeof(visit)); 17 queue<point>Q; 18 point now,next; 19 now.x=sx;now.y=sy; 20 now.time=6; 21 now.step=0; 22 visit[now.x][now.y]=1; 23 Q.push(now); 24 while (!Q.empty()) 25 { 26 now=Q.front(); 27 Q.pop(); 28 if (map[now.x][now.y]==3) 29 return now.step; 30 if (now.time<=1)continue; 31 for (i=0;i<4;i++) 32 { 33 next.x=now.x+dx[i]; 34 next.y=now.y+dy[i]; 35 if (next.x<1||next.x>n||next.y<1||next.y>m)continue; 36 if (map[next.x][next.y]==0)continue; 37 if (visit[next.x][next.y]==1)continue; 38 next.step=now.step+1; 39 next.time=now.time-1; 40 if (map[next.x][next.y]==4) 41 { 42 next.time=6; 43 visit[next.x][next.y]=1;//确保只走一次,标记 44 } 45 Q.push(next); 46 } 47 } 48 return -1; 49 } 50 int main() 51 { 52 int t,i,j,sx,sy; 53 while (~scanf("%d",&t)){ 54 while (t--) 55 { 56 scanf("%d %d",&n,&m); 57 for (i=1;i<=n;i++) 58 { 59 for (j=1;j<=m;j++) 60 { 61 scanf("%d",&map[i][j]); 62 if (map[i][j]==2) 63 { 64 sx=i; 65 sy=j; 66 } 67 } 68 } 69 printf("%d\n",bfs(sx,sy)); 70 } 71 } 72 return 0; 73 }