多个点求曼哈顿距离最大值的优化、二分查找将优化问题转化为判定问题、曼哈顿距离的另一种形式(适用于多次查询某点与多个点的曼哈顿距离的最大值)
对于曼哈顿距离存在另一种形式的计算:
等式右边两项分别对应于:x1和x2、y1和y2的大小关系相同和不同的情况。
这样做的好处是,对于多个(x2,y2)点,可以预处理出全部点的最大和最小的x2+y2、x2-y2,这样对于任意其他点,可以在O(1)计算出它和全部点的曼哈顿距离的最大值。
例题:
https://codingcompetitions.withgoogle.com/kickstart/round/00000000008f4a94/0000000000b55465#analysis
注意此题的优化思想,利用二分查找,将优化问题转化为判定某值是否可行。
代码:

#include<bits/stdc++.h> using namespace std; typedef long long LL; int grid[300][300]; void YD() { int r, c; cin >> r >> c; string str; for (int i = 1; i <= r; i++) { cin >> str; for (int j = 1; j <= c; j++) { grid[i][j] = str[j - 1] - '0'; } } deque<pair<int, int>> que; for (int i = 1; i <= r; i++) { for (int j = 1; j <= c; j++) { if (grid[i][j]) grid[i][j] = 0, que.push_back({ i,j }); else grid[i][j] = 1e8; } } while (que.size()) { auto[x, y] = que.front(); que.pop_front(); int dis = grid[x][y]; if (x + 1 <= r && grid[x + 1][y] > dis + 1) { grid[x + 1][y] = dis + 1; que.push_back({ x + 1,y }); } if (y + 1 <= c && grid[x][y + 1] > dis + 1) { grid[x][y + 1] = dis + 1; que.push_back({ x ,y + 1 }); } if (x - 1 > 0 && grid[x - 1][y] > dis + 1) { grid[x - 1][y] = dis + 1; que.push_back({ x - 1,y }); } if (y - 1 > 0 && grid[x][y - 1] > dis + 1) { grid[x][y - 1] = dis + 1; que.push_back({ x ,y - 1 }); } } int max_dis = 0; for (int i = 1; i <= r; i++) { for (int j = 1; j <= c; j++) max_dis = max(max_dis, grid[i][j]); } int l = 0, rr = max_dis; while (l < rr) { int mid = (l + rr) / 2; int add_max = -1e9, sub_max = -1e9; int add_min = 1e9, sub_min = 1e9; for (int i = 1; i <= r; i++) { for (int j = 1; j <= c; j++) { if (grid[i][j] > mid) { add_max = max(add_max, i + j); sub_max = max(sub_max, i - j); add_min = min(add_min, i + j); sub_min = min(sub_min, i - j); } } } bool flag = false; for (int i = 1; i <= r; i++) { for (int j = 1; j <= c; j++) { if (grid[i][j]!=0) { int max_dist = max({ abs(i + j - add_max), abs(i + j - add_min), abs(i - j - sub_max), abs(i - j - sub_min) }); if (max_dist <= mid) { flag = true; } } } } if (flag) { rr = mid; } else { l = mid + 1; } } cout << l << endl; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int T = 1; cin >> T; for (int i = 1; i <= T; i++) { cout << "Case #" << i << ": "; YD(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人