南陽理工OJ_題目306 走迷宮

//搜索+二分
//這道題還給了我一個教訓:深搜時,先判斷先一個結點是否滿足條件,然後再深搜,這樣程序要快很多!!! 
#include <iostream>
#include <cstring>

using namespace std;

bool fun(int mid);
void dfs(int x, int y, int l, int r);

int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
int n;
int a[110][110];
int vis[110][110];
int max_num;
int min_num;
bool flag;
int ma_mi;
int mid;

int main()
{
    while(cin >> n)
    {
        max_num = -1 << 30;
        min_num = 1 << 30;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
            {
                cin >> a[i][j];
                max_num = max_num > a[i][j] ? max_num : a[i][j];
                min_num = min_num < a[i][j] ? min_num : a[i][j];
            }
        int x, y;
        x = 0;
        y = max_num - min_num;
        while(x < y)
        {
            mid = (y + x) / 2;
            if(fun(mid) == true)
                y = mid;
            else
                x = mid+1;
        }
        cout << x << endl;
    }
}

bool fun(int mid)
{
    flag = 0;
    for(int k = min_num; k <= max_num - mid; k++)
    {
        if(a[1][1] < k || a[1][1] > k + mid)
            continue;
        if(a[n][n] < k || a[n][n] > k + mid)
            continue;
        memset(vis, 0, sizeof(vis));
        vis[1][1] = 1;
        dfs(1, 1, k, k+mid);
        if(flag == 1)
            return true;
    }
    return false;
}

void dfs(int x, int y, int l, int r)
{
    if(flag == 1)
        return;

    if(x == n && y == n)
    {
        flag = 1;
        return;
    }
    for(int i = 0; i < 4; i++)
    {
        int nx = dx[i] + x;
        int ny = dy[i] + y;
        if(nx < 1 || nx > n || ny < 1 || ny > n)
            continue;
        if(a[nx][ny] >= l && a[nx][ny] <= r && vis[nx][ny] == 0)
        {
            vis[nx][ny] = 1;
            dfs(nx, ny, l, r);
        }
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章