标签:
题意:在n×m的地图上,0表示墙,1表示空地,2表示人,3表示目的地,4表示有定时炸弹重启器。定时炸弹的时间是6,人走一步所需要的时间是1。每次可以上、下、左、右移动一格。当人走到4时如果炸弹的时间不是0,可以重新设定炸弹的时间为6。如果人走到3而炸弹的时间不为0时,成功走出。求人从2走到3的最短时间。这个题中每个结点都是可以重复访问的,但其实,炸弹重置点不要重复走,因为,走到炸弹重置点时时间就会被设置为最大时间,当重新返回时时间又设成最大,但此时已走的步数肯定增加了
Sample Input
3
3 3
2 1 1
1 1 0
1 1 3
4 8
2 1 1 0 1 1 1 0
1 0 4 1 1 0 4 1
1 0 0 0 0 0 0 1
1 1 1 4 1 1 1 3
5 8
1 2 1 1 1 1 1 4
1 0 0 0 1 0 0 1
1 4 1 0 1 1 0 1
1 0 0 0 0 3 0 1
1 1 4 1 1 1 1 1
Sample Output
4
-1
13
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <queue> 5 using namespace std; 6 7 int n , m ; 8 int sx , sy ; 9 int map[11][11] ; 10 int step[11][11] ; 11 int t[11][11] ; 12 int MIN ; 13 14 15 16 int dx[] = {1,-1,0,0} ; 17 int dy[] = {0,0,1,-1} ; 18 19 void dfs(int x ,int y , int len , int sum) 20 { 21 if (x<0 || y<0 || x>=n || y>=m || len <= 0 || sum >= MIN) 22 return ; 23 if (map[x][y] == 0) 24 return ; 25 if (map[x][y] == 3) 26 { 27 if (sum < MIN) 28 MIN = sum ; 29 return ; 30 } 31 if (map[x][y] == 4) 32 len = 6 ; 33 if (sum >= step[x][y] && len <=t[x][y] ) //如果转了一圈 又转回来了 就要剪掉 34 return ; 35 step[x][y] = sum ; //当前步数 36 t[x][y] = len ; //剩余时间 37 int fx , fy ; 38 for(int i = 0 ; i < 4 ; i++) 39 { 40 fx = x + dx[i] ; 41 fy = y + dy[i] ; 42 dfs(fx,fy,len-1,sum+1) ; 43 } 44 45 } 46 47 48 49 int main () 50 { 51 // freopen("in.txt","r",stdin) ; 52 int T ; 53 scanf("%d" , &T) ; 54 while (T--) 55 { 56 scanf("%d %d" , &n , &m) ; 57 for (int i = 0 ; i < n ; i++) 58 for (int j = 0 ; j < m ; j++) 59 { 60 cin>>map[i][j] ; 61 step[i][j] = INT_MAX ; 62 if (map[i][j] == 2) 63 { 64 sx = i ; 65 sy = j ; 66 } 67 68 69 } 70 memset(t , 0 ,sizeof(t)) ; 71 MIN = INT_MAX ; 72 int len = 6 ; 73 int sum = 0 ; 74 dfs(sx,sy,len,sum) ; 75 if (MIN == INT_MAX) 76 printf("-1\n") ; 77 else 78 printf("%d\n" , MIN) ; 79 80 } 81 82 return 0 ; 83 }
标签:
原文地址:http://www.cnblogs.com/-Buff-/p/4518477.html