打卡信奥刷题(1446)用C++实现信奥 P4955 [USACO14JAN] Cross Country Skiing S

P4955 [USACO14JAN] Cross Country Skiing S

题目描述

冬季 Moolympics 的越野滑雪赛道由一个 M × N M \times N M×N 的高程网格描述( 1 ≤ M , N ≤ 500 1 \leq M, N \leq 500 1M,N500),每个高程在 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考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值