思路:
利用了曼哈顿距离和切比雪夫距离之间的转化。
参考:
https://blog.csdn.net/Dylan_Frank/article/details/88985444
https://www.cnblogs.com/SGCollin/p/9636955.html
以后如果再遇到需要先计算大量曼哈顿距离然后再计算这些曼哈顿距离中的最大值的时候,就要考虑下是否可以转化为切比雪夫距离来优化了。
实现:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef pair<int, int> pii; 4 const int N = 255; 5 const int INF = 0x3f3f3f3f; 6 const int dx[4] = {0, 1, 0, -1}; 7 const int dy[4] = {1, 0, -1, 0}; 8 char a[N][N]; 9 int dis[N][N], vis[N][N]; 10 bool check(int k, int r, int c) 11 { 12 memset(dis, 0, sizeof dis); 13 memset(vis, 0, sizeof vis); 14 queue<pii> q; 15 for (int i = 0; i < r; i++) 16 { 17 for (int j = 0; j < c; j++) 18 { 19 if (a[i][j] == '1') 20 { 21 q.push(pii(i, j)); 22 vis[i][j] = 1; 23 dis[i][j] = 0; 24 } 25 } 26 } 27 int maxn = 0; 28 while (!q.empty()) 29 { 30 pii tmp = q.front(); q.pop(); 31 for (int i = 0; i < 4; i++) 32 { 33 int nx = tmp.first + dx[i], ny = tmp.second + dy[i]; 34 if (nx >= 0 && nx < r && ny >= 0 && ny < c && !vis[nx][ny]) 35 { 36 vis[nx][ny] = 1; 37 q.push(pii(nx, ny)); 38 dis[nx][ny] = dis[tmp.first][tmp.second] + 1; 39 maxn = max(maxn, dis[nx][ny]); 40 } 41 } 42 } 43 if (maxn <= k) return true; 44 int maxx = -INF, maxy = -INF, minx = INF, miny = INF; 45 for (int i = 0; i < r; i++) 46 { 47 for (int j = 0; j < c; j++) 48 { 49 if (dis[i][j] > k) 50 { 51 maxx = max(maxx, i + j); 52 minx = min(minx, i + j); 53 maxy = max(maxy, i - j); 54 miny = min(miny, i - j); 55 } 56 } 57 } 58 int ans = maxn; 59 for (int i = 0; i < r; i++) 60 { 61 for (int j = 0; j < c; j++) 62 { 63 if (a[i][j] == '1') continue; 64 int tx = i + j, ty = i - j, maxd = -INF; 65 maxd = max(maxd, abs(maxx - tx)); 66 maxd = max(maxd, abs(minx - tx)); 67 maxd = max(maxd, abs(maxy - ty)); 68 maxd = max(maxd, abs(miny - ty)); 69 ans = min(ans, maxd); 70 } 71 } 72 return ans <= k; 73 } 74 int main() 75 { 76 int T, r, c; 77 cin >> T; 78 for (int t = 1; t <= T; t++) 79 { 80 cin >> r >> c; 81 for (int i = 0; i < r; i++) 82 for (int j = 0; j < c; j++) 83 cin >> a[i][j]; 84 int L = 0, R = r + c, ans = INF; 85 while (L <= R) 86 { 87 int m = L + R >> 1; 88 if (check(m, r, c)) 89 { 90 R = m - 1; 91 ans = m; 92 } 93 else L = m + 1; 94 } 95 cout << "Case #" << t << ": " << ans << endl; 96 } 97 return 0; 98 }