题目描述
博艾市将要举行一场汽车拉力比赛。
赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间。
其中一些单元格被定义为路标。组织者希望给整个路线指定一个难度系数D,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于D。也就是说这个难度系数D指的是保证所有路标相互可达的最小值。任一单元格和其东西南北四个方向上的单元格都是相邻的。
输入输出格式
输入格式:
第一行两个整数M和N。第2行到第M+1行,每行N个整数描述海拔高度。第2+M行到第1+2M
行,每行N个整数,每个数非0即1,1表示该单元格是一个路标。
输出格式:
一个整数,即赛道的难度系数D。
输入输出样例
输入样例#1:
3 5
20 21 18 99 5
19 22 20 16 26
18 17 40 60 80
1 0 0 0 1
0 0 0 0 0
0 0 0 0 1
输出样例#1:
2
我必须要说说今天这个错误,我为了处理边界,给了周边的单元一个极小值,但负小了,所以就抄了边界。
!!!!注意
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int n,m,L,R,mid;
long long h[][];
int X,Y,cnt;
bool map[][];
int zh[][],vis[][];
int dx[]={,-,,},dy[]={,,,-};
bool check(int d)
{
memset(vis,,sizeof(vis));
int l=,r=,x,y,xx,yy,tot=cnt-;
l=,r=;
zh[r][]=X,zh[r][]=Y;vis[X][Y]=;
while(l < r)
{
x=zh[++l][],y=zh[l][];
for(int j=;j<;j++)
{ if(tot==) return ;
xx=x+dx[j],yy=y+dy[j];
if(abs(h[xx][yy]-h[x][y]) <=d && (!vis[xx][yy])&&x>=&&x<=m&&y>=&&y<=n)
{
zh[++r][]=xx;zh[r][]=yy; vis[xx][yy]=;
if(map[xx][yy])
tot--;
}
}
} return ;
}
int main()
{
scanf("%d%d",&m,&n);long long mi=,ma=;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
{
scanf("%lld",&h[i][j]);
mi=min(mi,h[i][j]);
ma=max(ma,h[i][j]);
} for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j])
X=i,Y=j,cnt++;
}
for(int i=;i<=m+;i++) h[i][]=h[i][n+]=-;
for(int j=;j<=n+;j++) h[][j]=h[m+][j]=-;
L=,R=ma-mi;//+100
while(L+<R)
{
mid=(L+R)/;
if(check(mid))
R=mid;
else L=mid;
}
for(L;L<=R;L++)
if(check(L)){
cout<<L;
return ;
}
cout<<L;
return ;
}