题目链接:
题目描述:
有一个n*m由0 or 1组成的矩形,探险家要从(1,1)走到(n, m),可以向上下左右四个方向走,但是探险家就是不走寻常路,他想让他所走的路线上的0/1组成的二进数最小,现在要为矫情无比的探险家找最优路径咯。
解题思路:
对于二进制数,前导零是对数字大小没有任何影响的。当到不得不走1的时候就只能向下,或者向右走了。所以先搜索出来一直走零,能走到的最靠近终点的位置,然后在类似搜索,找出最优路径。
1 #include <queue> 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int maxn = 1010; 8 struct node 9 { 10 int x, y; 11 }; 12 char maps[maxn][maxn]; 13 bool vis[maxn][maxn]; 14 int dir[4][2] = {1,0, 0,1, -1,0, 0,-1}; 15 int x, y, n, m; 16 bool Ok (int x, int y) 17 { 18 if (x<0 || y<0 || x>=n || y>=m) 19 return false; 20 return true; 21 } 22 void bfs () 23 { 24 node p, q; 25 p.x = x, p.y = y; 26 queue <node> Q; 27 Q.push (p); 28 while (!Q.empty()) 29 { 30 p = Q.front(); 31 Q.pop(); 32 for (int i=0; i<4; i++) 33 { 34 q.x = p.x + dir[i][0]; 35 q.y = p.y + dir[i][1]; 36 if (Ok(q.x, q.y) && !vis[q.x][q.y]) 37 { 38 vis[q.x][q.y] = true; 39 if (maps[q.x][q.y] == ‘0‘) 40 Q.push (q); 41 if (x + y < q.x + q.y) 42 x = q.x, y = q.y; 43 } 44 } 45 } 46 } 47 int main () 48 { 49 int t; 50 scanf ("%d", &t); 51 while (t --) 52 { 53 memset (vis, false, sizeof(vis)); 54 vis[0][0] = true; 55 scanf ("%d %d", &n, &m); 56 for (int i=0; i<n; i++) 57 scanf ("%s", maps[i]); 58 x = y = 0; 59 if (maps[x][y] == ‘0‘) 60 bfs (); 61 if (maps[x][y] == ‘0‘) 62 putchar(‘0‘); 63 else 64 { 65 bool nowflag = false; 66 putchar (‘1‘); 67 for (int i=x+y; i<n+m-2; i++) 68 { 69 bool flag = false; 70 for (x=0; x<=i; x++) 71 { 72 y = i - x; 73 if (!Ok(x, y) || !vis[x][y]) 74 continue; 75 if (nowflag && maps[x][y]==‘1‘) 76 continue; 77 for (int j=0; j<2; j++) 78 { 79 int a = x + dir[j][0]; 80 int b = y + dir[j][1]; 81 if (!Ok(a, b)) 82 continue; 83 vis[a][b] = true; 84 if (maps[a][b] == ‘0‘) 85 flag = true; 86 } 87 } 88 nowflag = flag; 89 putchar (flag?‘0‘:‘1‘); 90 } 91 } 92 puts(""); 93 } 94 return 0; 95 }
时间: 2024-11-06 14:36:35