学习自此博客题解
二分搜索+深搜。二分枚举最小差距值(路径上的最大值与最小值的差距),枚举的最小值为abs(a[1][1]-a[n][n]),最大值为题目给出的120。搜索时代入这个最小差距值,若存在一条路径满足这个最小差距值则符合条件,也就可以继续试图枚举更小的差距值。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define N 102 #define INF 0x7fffffff const int maxv = 120; int v[N][N]; bool vis[N][N]; int dir[4][2] = {1,0, 0,1, -1,0, 0,-1}; int n; bool dfs(int x, int y, int low, int high) { if(x<1 || y<1 || x>n || y>n) return false; if(vis[x][y]) return false; if(v[x][y] < low || v[x][y] > high) return false; if(x == n && y == n) return true; vis[x][y] = true; for(int i=0; i<4; i++) if(dfs(x+dir[i][0], y+dir[i][1], low, high)) return true; return false; } bool solve(int gap) { for(int i=0; i<=maxv; i++){ memset(vis, false, sizeof(vis)); if(dfs(1,1,i,i+gap)) return true; } return false; } int binary_search() { int left = abs(v[1][1]-v[n][n]); int right = maxv; int mid; while(left <= right){ mid = left+(right-left)/2; if(solve(mid)){ right = mid-1; } else left = mid+1; } return mid; } int main() { freopen("d:\\in.txt", "r", stdin); while(~scanf("%d", &n)) { for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) scanf("%d", &v[i][j]); printf("%d\n", binary_search()); } }