zoukankan      html  css  js  c++  java
  • poj2110

    题意:给定一个矩阵,从左上角到右下角,使走过的路径中数字的最大值最小值之差最小,问差最小是多少。

    分析:首先不能用bfs,priority_queue以下两组数据可以说明问题。

    有时候不能先扩展最优的。

    2
    5 6
    1 1


    3
    5 6 1
    1 3 5
    1 7 1

    正确的方法是二分这个差值a,对于每个二分结果枚举范围d~d+a,然后进行bfs,只有矩阵上的数字在d到d+a之间的格子才可以走。看能否到达终点。

    View Code
    #include <iostream>
    #include
    <cstdio>
    #include
    <cstdlib>
    #include
    <cstring>
    using namespace std;

    #define maxn 115

    struct Node
    {
    int x, y;
    } q[maxn
    * maxn];

    int n, u, d;
    int map[maxn][maxn];
    bool vis[maxn][maxn];
    int dir[4][2] =
    {
    {
    1, 0 },
    {
    0, 1 },
    {
    -1, 0 },
    {
    0, -1 } };

    void input()
    {
    u
    = 0;
    d
    = maxn;
    for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
    {
    scanf(
    "%d", &map[i][j]);
    d
    = min(map[i][j], d);
    u
    = max(map[i][j], u);
    }
    }

    bool ok(Node &a, int u, int d)
    {
    if (a.x < 0 || a.y < 0 || a.x >= n || a.y >= n)
    return false;
    return !vis[a.x][a.y] && map[a.x][a.y] <= u && map[a.x][a.y] >= d;
    }

    bool bfs(int d, int u)
    {
    q[
    0].x = 0;
    q[
    0].y = 0;
    int front = 0;
    int rear = 1;
    memset(vis,
    0, sizeof(vis));
    vis[
    0][0] = true;
    while (front != rear)
    {
    Node temp
    = q[front++];
    if (front == maxn * maxn)
    front
    = 0;
    for (int i = 0; i < 4; i++)
    {
    Node a;
    a.x
    = temp.x + dir[i][0];
    a.y
    = temp.y + dir[i][1];
    if (ok(a, u, d))
    {
    q[rear
    ++] = a;
    if (rear == maxn * maxn)
    rear
    = 0;
    vis[a.x][a.y]
    = true;
    }
    }
    }
    return vis[n - 1][n - 1];
    }

    bool reach(int a)
    {
    for (int i = max(max(d, map[n - 1][n - 1] - a), map[0][0] - a); i <= min(
    min(u
    - a, map[0][0]), map[n - 1][n - 1]); i++)
    if (bfs(i, i + a))
    return true;
    return false;
    }

    void binarysearch()
    {
    int l = abs(map[n - 1][n - 1] - map[0][0]);
    int r = u - d;
    while (l < r)
    {
    int mid = (l + r) / 2;
    if (reach(mid))
    r
    = mid;
    else
    l
    = mid + 1;
    }
    printf(
    "%d\n", l);
    }

    int main()
    {
    //freopen("t.txt", "r", stdin);
    scanf("%d", &n);
    input();
    binarysearch();
    return 0;
    }
  • 相关阅读:
    Docker03-镜像
    Docker02:Centos7.6安装Docker
    Docker01-重要概念
    WEB开发新人指南
    Lpad()和Rpad()函数
    Unable to find the requested .Net Framework Data Provider. It may not be installed
    redis自动过期
    redis简单的读写
    redis的安装
    Ajax缓存,减少后台服务器压力
  • 原文地址:https://www.cnblogs.com/rainydays/p/2111404.html
Copyright © 2011-2022 走看看