P4955 [USACO14JAN] Cross Country Skiing S
题目描述
冬季 Moolympics 的越野滑雪赛道由一个 M × N M \times N M×N 的高程网格描述( 1 ≤ M , N ≤ 500 1 \leq M, N \leq 500 1≤M,N≤500),每个高程在 0 0 0 到 1 , 000 , 000 , 000 1,000,000,000 1,000,000,000 之间。网格中的某些单元被指定为赛道的航点。Moolympics 的组织者希望为整个赛道分配一个难度等级 D D D,以便奶牛可以通过从一个单元滑到相邻单元(绝对高程差最多为 D D D)的方式,从任何一个航点到达另一个航点。如果一个单元的正北、正南、正东或正西方向上有另一个单元,则这两个单元是相邻的。赛道的难度等级是 D D D 的最小值,使得所有航点都可以通过这种方式相互到达。
输入格式
-
第 1 行:整数 M M M 和 N N N。
-
第 2 行到第 1 + M 1+M 1+M 行:每一行包含 N N N 个整数高程。
-
第 2 + M 2+M 2+M 行到第 1 + 2 M 1+2M 1+2M 行:每一行包含 N N N 个值,这些值要么是 0 0 0,要么是 1 1 1,其中 1 1 1 表示该单元是一个航点。
输出格式
滑雪赛道由一个 3 x 5 的高程网格描述。左上角、右上角和右下角的单元被指定为航点。
输入输出样例 #1
输入 #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
说明/提示
如果 D = 21 D = 21 D=21,三个航点可以相互到达。如果 D < 21 D < 21 D<21,则右上角的航点无法从其他两个航点到达。
题面翻译由 ChatGPT-4o 提供。
C++实现
#include<bits/stdc++.h>
using namespace std;
const int N=505;
int a[N][N],b[N][N];
int vis[N][N];
int x,y;int n,m;
int nx[]={0,0,1,-1};
int ny[]={1,-1,0,0};
queue<pair<int,int> > q;
inline bool check(int mid){
memset(vis,0,sizeof(vis));
vis[x][y]=1;
q.push(make_pair(x,y));
while(!q.empty()){
pair<int,int> p=q.front();q.pop();
int px=p.first,py=p.second;
for(int i=0;i<4;i++){
int tx=px+nx[i],ty=py+ny[i];
if(tx<1||ty<1||tx>n||ty>m) continue;
if(!vis[tx][ty]&&abs(a[tx][ty]-a[px][py])<=mid){
vis[tx][ty]=1;
q.push(make_pair(tx,ty));
}
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(b[i][j]&&!vis[i][j]) return 0;
return 1;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
scanf("%d",&b[i][j]);
if(b[i][j]) x=i,y=j;
}
int l=0,r=1e9+1,mid,ans;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)) r=mid-1,ans=mid;
else l=mid+1;
}
printf("%d",ans);
return 0;
}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容