0
点赞
收藏
分享

微信扫一扫

洛谷P2658 汽车拉力比赛 题解 二分答案+搜索

题目链接:​​https://www.luogu.com.cn/problem/P2658​​

解题思路:

这道题当D确定的情况下,其实就是一个连通块问题。

然后我们二分答案求最小的D即可。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 550;
int n, m, h[maxn][maxn], flag[maxn][maxn], sx, sy;
bool vis[maxn][maxn];
int dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 };
inline bool inmap(int x, int y) {
return x>=0 && x<n && y>=0 && y<m;
}
void find_sx_sy() {
for (int i = 0; i < n; i ++)
for (int j = 0; j < m; j ++)
if (flag[i][j]) {
sx = i; sy = j; return;
}
}
void dfs(int x, int y, int D) {
vis[x][y] = true;
for (int i = 0; i < 4; i ++) {
int xx = x + dir[i][0], yy = y + dir[i][1];
if (inmap(xx, yy) && !vis[xx][yy] && abs(h[x][y]-h[xx][yy]) <= D)
dfs(xx, yy, D);
}
}
bool in_check() {
for (int i = 0; i < n; i ++) for (int j = 0; j < m; j ++)
if (flag[i][j] && !vis[i][j]) return false;
return true;
}
bool check(int D) {
memset(vis, 0, sizeof(vis));
dfs(sx, sy, D);
return in_check();
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i ++) for (int j = 0; j < m; j ++) cin >> h[i][j];
for (int i = 0; i < n; i ++) for (int j = 0; j < m; j ++) cin >> flag[i][j];
find_sx_sy();
int L = 0, R = 1000000000, res;
while (L <= R) {
int mid = (L + R) / 2;
if (check(mid)) res = mid, R = mid-1;
else L = mid+1;
}
cout << res << endl;
return 0;
}

​​洛谷P3073​​ 和这题一样。


举报

相关推荐

0 条评论