zoukankan      html  css  js  c++  java
  • 洛谷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 和这题一样。

  • 相关阅读:
    读取xml文件到实体
    dev常用控件的属性
    委托和事件
    GridControl应用
    关于DataTable的处理
    SQL2
    xaml地址写法
    sql临时表的创建及赋值
    wpf 图片缩放
    NIO简介
  • 原文地址:https://www.cnblogs.com/quanjun/p/12344663.html
Copyright © 2011-2022 走看看