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; }