DFS+二分_NYOJ_306

来源:互联网 发布:什么是好的相声知乎 编辑:程序博客网 时间:2024/04/30 21:01

题意:
在n*n的矩阵中,寻找(1,1)->(n,n)的路径中,最大值和最小值差值最小
解:二分差值(差值肯定<=max(矩阵)-min(矩阵)和在[n][n]-[0][0]之间),枚举最小值,看能否找到一条路,特别的,注意起点的判断/http://acm.nyist.net/JudgeOnline/problem.php?pid=306&rec=sim/,

#include<iostream>#include<cstdio>#include<cstring>#define oo 0x3f3f3f3fconst int maxn = 105;using namespace std;int map[maxn][maxn],vis[maxn][maxn],n,flag;int fx[] = {-1,1,0,0};int fy[] = {0,0,-1,1};int dfs(int x, int y, int ma,int mb){    if(x == n && y == n)    {        flag = 1;        return 1;    }    for(int i = 0; i < 4 && !flag; i++)    {        int xi = x+fx[i];        int yi = y+fy[i];        if(xi>=1&&xi<=n&&yi>=1&&yi<=n&&!vis[xi][yi])        {            if(map[xi][yi]>=ma && map[xi][yi]<=mb)            {                vis[xi][yi] = 1;                if(dfs(xi,yi,ma,mb))                    return 1;            }        }    }    return 0;}int main(){    int mn,mx,min1,max1,mid,ans;    while(scanf("%d",&n)!=EOF)    {        mn = 130;        mx = 0;        for(int i = 1;i <= n; i++)        {            for(int j = 1; j <= n; j++)            {                scanf("%d",&map[i][j]);                mn = mn<map[i][j]?mn:map[i][j];                mx = mx>map[i][j]?mx:map[i][j];            }        }        min1 = map[n][n]-map[1][1];        min1=min1>0?min1:-min1;        max1 = mx-mn;        while(min1 <= max1)        {            mid = (min1+max1)/2;            flag = 0;            for(int i = mn; i <=(mx-mid);i++)            {                memset(vis,0,sizeof(vis));                vis[1][1] = 1;                if(i>map[1][1])break;                if(i+mid < map[0][0])continue;                if(dfs(1,1,i,i+mid))                {                    ans = mid;                    max1 = mid-1;                    break;                }            }            if(!flag)            {                min1 = mid+1;            }        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击