//求(1,1)到(n,n)的一条路径。这条路径的最大值和最小值差最小
//2分+dfs
//首先枚举差值,确定这次枚举的最小的最小值,因为从1,1开始且差值确定,故下界也可确定
//然后枚举从下界到1,1的高度,进行dfs即可
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=202;
int map[maxn][maxn],n,t,flag,vis[maxn][maxn];
int dx[]= {1,-1,0,0};
int dy[]= {0,0,1,-1};
int inmap(int x,int y)
{
if(x<=0||y<=0||x>n||y>n)return 0;
return 1;
}
void dfs(int x,int y,int l,int r)
{
if(map[x][y]<l||map[x][y]>r)return;
if(x==n&&y==n)
{
flag=1;
return ;
}
for(int i=0; i<=3; i++)
{
int x1=x+dx[i];
int y1=y+dy[i];
if(inmap(x1,y1)&&!vis[x1][y1]&&!flag)
{
vis[x1][y1]=1;
dfs(x1,y1,l,r);
}
}
}
void init()
{
for(int i=0; i<=n; i++)
{
for(int j=0; j<=n; j++)
{
vis[i][j]=0;
}
}
}
int main()
{
cin>>t;
int i,j,k,l,r,mmin,mmax;
for(i=1; i<=t; i++)
{
scanf("%d",&n);
mmin=300;
mmax=0;
for(j=1; j<=n; j++)
{
for(k=1; k<=n; k++)
{
scanf("%d",&map[j][k]);
vis[j][k]=0;
mmin=min(mmin,map[j][k]);
mmax=max(mmax,map[j][k]);
}
}
int low;
int high;
int x=0,y=mmax-mmin;
while(x<=y)
{
int mid=(x+y)>>1;
low=map[1][1]-mid>0?map[1][1]-mid:0;//决定路径中的最小高度
high=low+mid; //路径中最大高度
while(low<=map[1][1])
{
init();
flag=0;
vis[1][1]=1;
dfs(1,1,low,high);
if(flag)break;
low++;
high++;
}
if(low>map[1][1])x=mid+1;
else y=mid-1;
}
printf("Scenario #%d:\n",i);
printf("%d\n\n",x);
}
return 0;
}
/*
2
5
1 1 3 6 8
1 2 2 5 5
4 4 0 3 3
8 0 2 2 4
4 3 0 3 1
*/
poj 2922 dfs
最新推荐文章于 2017-03-31 16:27:50 发布