题目描述
博艾市将要举行一场汽车拉力比赛。
赛场凹凸不平,所以被描述为 N∗MN∗M 的网格来表示海拔高度 (1≤M,N≤500)(1≤M,N≤500),每个单元格的海拔范围在 00 到 109109 之间。
其中一些单元格被定义为路标。组织者希望给整个路线指定一个难度系数 DD,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于 DD 。也就是说这个难度系数 DD 指的是保证所有路标相互可达的最小值。任一单元格和其东西南北四个方向上的单元格都是相邻的。
输入格式
第 11 行两个整数 MM 和 NN。第 22 行到第 M+1M+1 行,每行 NN 个整数描述海拔高度。第 2+M2+M 行到第 1+2M1+2M
行,每行 NN 个整数,每个数非 00 即 11,11 表示该单元格是一个路标。
输出格式
一个整数,即赛道的难度系数 DD。
输入输出样例
输入 #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
21
源码
#include <iostream>
#define MAXSIZE 501
#include <utility>
#include <cstring>
using namespace std;
typedef pair<int,int> PII;
PII q[MAXSIZE*MAXSIZE];
int m,n;
int high[MAXSIZE][MAXSIZE];
int flag[MAXSIZE][MAXSIZE];
int flag_num=0;
int x1,y1;
int dx[]={-1,0,1,0};
int dy[]={0,1,0,-1};
int st[MAXSIZE][MAXSIZE];
int check(int mid){
int hh=0,tt=-1;
int flag_cnt=1;
st[x1][y1]=1;
q[++tt]={x1,y1};
while(hh<=tt){
auto t=q[hh++];
for(int i=0;i<4;i++){
int a=t.first+dx[i];
int b=t.second+dy[i];
if(st[a][b]) continue;
if(a<1 || a>m || b<1 || b>n) continue;
if(abs(high[t.first][t.second]-high[a][b])>mid) continue;
q[++tt]={a,b};
st[a][b]=1;
if(flag[a][b]==1){
flag_cnt++;
if(flag_cnt==flag_num){
return 1;
}
}
}
}
return 0;
}
int main(){
scanf("%d %d",&m,&n);
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
scanf("%d",&high[i][j]);
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
scanf("%d",&flag[i][j]);
if(flag[i][j]==1) flag_num++;
}
}
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
if(flag[i][j]==1){
x1=i,y1=j;
break;
}
}
}
int l=-1,r=1e9+1;
while(l+1<r){
memset(q,0,sizeof(q));
memset(st,0,sizeof(st));
int mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
}
if(check(l)) printf("%d",l);
else
printf("%d\n",r);
return 0;
}