2024年6月19日-暑期实习-第三题(300分)-塔子哥的农田修复

在线评测链接

问题描述

塔子哥的农田受到地震的破坏,农田中的一些网点断开了联系。假设原本的农田网构成一个矩形,其中未被破坏的网点标记为 1 1 1,被破坏的网点标记为 0 0 0。标记为 1 1 1 的网点连在一起构成一个子网。现在,塔子哥需要找到一个目标网点,并找出离它最近的其他子网。请注意,两个网点相连只能通过上下左右四个方向,不可以通过斜对角相连。两个网点的距离定义为从一个网点(假设网点名为 C C C)到达另一个网点(假设网点名为 D D D)需要经过相连网点的最小数目( C C C D D D 这两个网点不计算在内)。两个子网(假设分别为 A A A 网和 B B B 网)不相连, A A A 网中所有的网点与 B B B 网中所有的网点的距离中最小的那个即为 A A A 网和 B B B 网的最小距离。

输入格式

第一行包含两个正整数 x , y x, y x,y,表示目标网点的坐标位置( x x x 表示行号, y y y 表示列号)。

第二行包含两个正整数 n , m n, m n,m,表示农田矩形的行数 n n n 和列数 m m m

接下来的 n n n 行每行包含 m m m 个以空格分隔的整数 0 0 0 1 1 1,表示农田网点的破坏情况。

输出格式

输出一个整数,表示最近的未被破坏子网的距离。如果整网中只有一个子网,则返回 − 1 -1 1

样例输入

1 1
6 6
1 1 0 0 1 0
1 1 0 0 1 1
0 0 0 0 1 0
0 1 0 1 0 0
1 1 0 0 0 0
1 1 1 0 1 1

样例输出

1

评测数据与规模

  • 1 ≤ n , m ≤ 1000 1 \leq n, m \leq 1000 1n,m1000
  • 输入保证目标网点是未被破坏的网点,且目标网点所在子网是一个子网。

题解

该题为力扣的改编题 1162. 地图分析

本题需要求当前区域到其他所有区域的最短 曼哈顿距离

我们分两次 BFS 来求出最短距离

  • 第一次BFS的目的是标记不同的区域
  • 第二次BFS的目的是求最短距离。

AC代码

from collections import deque
sx, sy = map(int, input().split())
sx -= 1
sy -= 1
n, m = map(int, input().split())
g = [list(map(int, input().split())) for _ in range(n)]
idx = 2
dx = [-1, 0, 1, 0]
dy = [0, 1, 0, -1]
def bfs(x, y, c):
    q = deque()
    q.append([x, y]) 
    g[x][y] = c
    while len(q):
        x, y = q.popleft()
        for i in range(4):
            a, b = x + dx[i], y + dy[i]
            if a < 0 or a >= n or b < 0 or b >= m or g[a][b] != 1:
                continue
            q.append([a, b])
            g[a][b] = c
for i in range(n):
    for j in range(m):
        if g[i][j] == 1:
            bfs(i, j, idx)
            idx += 1
if idx <= 3:
    print(-1)
else:
    color = g[sx][sy]
    q = deque()
    st = set()
    d = [[float('inf')] * m for _ in range(n)]
    for i in range(n):
        for j in range(m): 
            if g[i][j] == color:
                q.append([i, j])
                st.add((i, j))
                d[i][j] = 0
    res = 0
    while len(q):
        x, y = q.popleft()
        if g[x][y] != color and g[x][y]:
            res = d[x][y]
            break 
        for i in range(4):
            a, b = x + dx[i], y + dy[i]
            if a < 0 or a >= n or b < 0 or b >= m or (a, b) in st:
                continue
            q.append([a, b])
            d[a][b] = d[x][y] + 1
            st.add((a, b))
    print(res - 1)
        
  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔子哥学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值