POJ-2110 Mountain Walking
Mountain Walking
二分 + \(bfs\)
最终要求的最低差
二分答案,枚举最低海拔,这样就有一个能够接受的海拔范围 \([l, r]\)
根据这个范围,看看 \(bfs\) 能不能搜索到 \((n, n)\)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 120;
#define pii pair<int, int>
int num[maxn][maxn], n, vis[maxn][maxn];
const int xi[4] = {0, 0, 1, -1};
const int yi[4] = {1, -1, 0, 0};
bool check(int x, int y)
{
return x >= 1 && y >= 1 && x <= n && y <= n && vis[x][y] == 0;
}
bool bfs(int l, int r)
{
queue<pii>q;
for(int i=0; i<=n; i++)
for(int j=0; j<=n; j++)
vis[i][j] = 0;
if(num[1][1] <= r && num[1][1] >= l) q.push(make_pair(1, 1));
while(q.size())
{
pii now = q.front();
q.pop();
if(vis[now.first][now.second]) continue;
vis[now.first][now.second] = 1;
for(int i=0; i<4; i++)
{
int xx = now.first + xi[i];
int yy = now.second + yi[i];
if(check(xx, yy) && num[xx][yy] >= l && num[xx][yy] <= r)
q.push(make_pair(xx, yy));
}
}
return vis[n][n];
}
bool query(int len)
{
for(int i=len; i<=110; i++)
if(bfs(i - len, i)) return true;
return false;
}
int main()
{
scanf("%d", &n);
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
scanf("%d", &num[i][j]);
int l = 0, r = 110;
while(l < r)
{
int mid = l + r >> 1;
if(query(mid)) r = mid;
else l = mid + 1;
}
printf("%d\n", l);
return 0;
}