POJ - 2110 - Mountain Walking(二分/bfs)

题目链接:https://vjudge.net/problem/POJ-2110

题目描述:让你从图中选出一条从左上角到右下角的路,求这条路上最大的点和最小的点的差值

因为差值只有0~110,所以我们直接二分一个差值然后在bfs即可

#include<set>
#include<map>
#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<climits>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define endl '\n'
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
#define mst0(a) memset(a, 0, sizeof(a))
#define mstnil(a) memset(a, -1, sizeof(a))
#define mstinf(a) memset(a, 0x3f3f3f3f, sizeof(a))
#define IOS ios::sync_with_stdio(false)
#define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n")
using namespace std;
typedef long long ll;
typedef pair<int, int> P;
const double pi = acos(-1.0);
const double eps = 1e-7;
const ll MOD = 1e9+7;
const int INF = 0x3f3f3f3f;
const int NIL = -1;
int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
template<typename T> ll read(T &x){
    x = 0; char ch = getchar(); ll fac = 1;
    while(!isdigit(ch)) { if(ch == '-') fac*=-1; ch = getchar(); }
    while(isdigit(ch)) { x = x*10+ch-48; ch = getchar(); } x*=fac; return x;
}
const int maxn = 1e2+10;
int __map[maxn][maxn];
bool vis[maxn][maxn];
bool bfs(int low, int high, int n) {
    if (__map[0][0] < low || __map[0][0] > high)
        return false;
    mst0(vis);
    queue<P> qe;
    qe.push(make_pair(0, 0));
    vis[0][0] = true;
    while(!qe.empty()) {
        P t = qe.front();
        if (t.first == t.second && t.first == n-1)
            return true;
        qe.pop();
        for (int i = 0; i<4; ++i) {
            int xx = t.first+dx[i], yy = t.second+dy[i];
            if (!vis[xx][yy] && xx >= 0 && xx < n && yy >= 0 && yy < n && __map[xx][yy] >= low && __map[xx][yy] <= high) {
                qe.push(make_pair(xx, yy));
                vis[xx][yy] = true;
            }
        }
    } 
    return false;
}
bool check(int m, int n) {
    for (int i = 0; i+m<=110; ++i)
        if (bfs(i, i+m, n))
            return true;
    return false;
}
int main(void) {
    IOS;
    int n;
    while(cin >> n) {
        for (int i = 0; i<n; ++i)
            for (int j = 0; j<n; ++j)
                cin >> __map[i][j];
        int l = 0, r = 110;
        while(l <= r) {
            int m = (l+r)/2;
            if (check(m, n))
                r = m-1;
            else 
                l = m+1;
        }
        cout << l << endl;
    }
    return 0;
}

 

posted @ 2020-02-29 19:16  shuitiangong  阅读(148)  评论(0编辑  收藏  举报