BFS+贪心 HDOJ 5335 Walk Out

时间:2021-09-04 15:34:01

题目传送门

 /*
题意:求从(1, 1)走到(n, m)的二进制路径值最小
BFS+贪心:按照标程的作法,首先BFS搜索所有相邻0的位置,直到1出现。接下去从最靠近终点的1开始,
每一次走一步,不走回头路,只往下或往右走。因为满足i = j + (i - j)的坐标(j, i - j)可能不止一个,选择最小的访问
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std; const int MAXN = 1e3 + ;
const int INF = 0x3f3f3f3f;
int dx[] = {, , , -};
int dy[] = {, , -, };
char maze[MAXN][MAXN];
bool vis[MAXN][MAXN];
int n, m; bool judge(int x, int y) {
if (x < || x > n || y < || y > m || vis[x][y]) return false;
return true;
} void BFS(void) {
memset (vis, false, sizeof (vis)); int mx = ;
queue<pair<int, int> > Q; Q.push (make_pair (, )); vis[][] = true;
while (!Q.empty ()) {
int x = Q.front ().first, y = Q.front ().second; Q.pop ();
if (maze[x][y] == '') {
for (int i=; i<; ++i) {
int tx = x + dx[i], ty = y + dy[i];
if (!judge (tx, ty)) continue;
mx = max (mx, tx + ty);
Q.push(make_pair (tx, ty)); vis[tx][ty] = true;
}
}
} if (vis[n][m] && maze[n][m] == '') {
puts (""); return ;
} printf ("");
for (int i=mx; i<n+m; ++i) {
char mn = '';
for (int j=; j<=n; ++j) {
if ( <= i - j && i - j <= m && vis[j][i-j]) {
mn = min (mn, maze[j+][i-j]);
mn = min (mn, maze[j][i-j+]);
}
}
printf ("%c", mn);
for (int j=; j<=n; ++j) {
if ( <= i - j && i - j <= m && vis[j][i-j]) {
if (maze[j+][i-j] == mn) vis[j+][i-j] = true;
if (maze[j][i-j+] == mn) vis[j][i-j+] = true;
}
}
}
puts ("");
} int main(void) { //HDOJ 5335 Walk Out
//freopen ("I.in", "r", stdin);
int T; scanf ("%d", &T);
while (T--) {
scanf ("%d%d", &n, &m);
for (int i=; i<=n; ++i) scanf ("%s", maze[i] + );
for (int i=; i<=n; ++i) maze[i][] = maze[i][m+] = '';
for (int i=; i<=m+; ++i) maze[][i] = maze[n+][i] = '';
BFS ();
} return ;
}