hdu1728 逃离迷宫---转弯次数不超过k+BFS
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1728
题目大意:
给你一幅图,给出起点终点和最大转弯次数,判断是否能从起点到终点。‘*‘表示障碍物。
思路:
刚看到题目的时候有人会立刻想到对四个方向一步一步进行 BFS, 其实这样是不行的 , 因为当从两条路径 BFS 到同一点的时候 , 要选择其中一个继续 BFS, 如果转弯数都相同的话 , 就很难判断哪条路径有可能通向终点 . 所以 , 这种方法行不通 .
而这题的解法就是对四个方向 BFS, 但不是一步一步 , 也就是搜一个方向的时候一直搜索到沿这个方向能走到的尽头 , 这样搜的话 , 能够保证搜过的路径的转弯次数都是最小的 ( 因为这是基于转弯次数从 0 到 k 的 BFS).
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<string> 6 #include<queue> 7 using namespace std; 8 typedef long long ll; 9 const int INF = 1<<30; 10 const int maxn = 100000; 11 int T, cases; 12 int n, m, k, x1, y1, x2, y2; 13 char Map[105][105]; 14 bool vis[105][105]; 15 int dir[4][2] = {0,1,1,0,-1,0,0,-1}; 16 struct node 17 { 18 int x, y, time; 19 node(){} 20 node(int x, int y, int time):x(x), y(y), time(time){} 21 }; 22 bool judge(int x, int y) 23 { 24 return (x >= 0 && x < n && y >= 0 && y < m && !vis[x][y] && Map[x][y] == '.'); 25 } 26 void bfs() 27 { 28 queue<node>q; 29 q.push(node(x1, y1, -1));//-1表示起点 30 while(!q.empty()) 31 { 32 node a = q.front(); 33 q.pop(); 34 if(a.time > k)break; 35 if(a.x == x2 && a.y == y2) 36 { 37 printf("yes\n"); 38 return; 39 } 40 vis[a.x][a.y] = 1; 41 //vis放在这里是因为一个位置可能多次经过,因为从不同方向上,但是拿出队列之后就一定不能再次经过了 42 for(int i = 0; i < 4; i++) 43 { 44 int xx = a.x + dir[i][0]; 45 int yy = a.y + dir[i][1]; 46 while(judge(xx, yy))//往一个方向走到底 47 { 48 q.push(node(xx, yy, a.time + 1)); 49 xx += dir[i][0]; 50 yy += dir[i][1]; 51 } 52 } 53 } 54 printf("no\n"); 55 return; 56 } 57 int main() 58 { 59 cin >> T; 60 while(T--) 61 { 62 memset(vis, 0, sizeof(vis)); 63 cin >> n >> m; 64 for(int i = 0; i < n; i++)cin >> Map[i]; 65 cin >> k >> y1 >> x1 >> y2 >> x2; 66 x1--, y1--, x2--, y2--; 67 bfs(); 68 } 69 }
越努力,越幸运