学习自此博客题解

二分搜索+深搜。二分枚举最小差距值(路径上的最大值与最小值的差距),枚举的最小值为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());
    } 
}
 posted on 2015-04-04 10:15  平和之心  阅读(267)  评论(0编辑  收藏  举报