华为OD机试 - 矩阵扩散( Python & Java)

题目描述

存在一个m*n的二维数组,其成员取值范围为0,1。其中值为1的元素具备扩散性,每经过1S,将上下左右值为0的元素同化为1。将数组所有成员初始化为0,将矩阵的[i, j]和[m,n]位置上元素修改成1后,在经过多长时间所有元素变为1。

输入描述

输入的前两个数字是矩阵大小。后面是数字矩阵内容。

输出描述

输出矩阵的所有元素变为1所需要秒数。

用例

输入4,4,0,0,3,3
输出3
说明

输入数据中的前2个数字表示这是一个4*4的矩阵;

中间两个数字表示一个初始扩散点位置为0,0;

最后2个数字表示另一个扩散点位置为3,3。

给出的样例是一个简单模型,初始点在对角线上,达到中间的位置分别为3次迭代,即3秒。所以输出为3。

Python代码:

# 输入获取
m, n, i, j, x, y = map(int, input().split(","))


# 算法入口
def getResult(m, n, i, j, x, y):
    """
    :param m: 矩阵行数
    :param n: 矩阵列数
    :param i: 扩散点1行号
    :param j: 扩散点1列号
    :param k: 扩散点2行号
    :param l: 扩散点2列号
    :return: 矩阵的所有元素变为1所需要秒数
    """
    matrix = [[0 for _ in range(n)] for _ in range(m)]
    matrix[i][j] = 1
    matrix[x][y] = 1

    # count记录未被扩散的点的数量
    count = m * n - 2

    # 多源BFS实现队列
    queue = [[i, j], [x, y]]

    # 上下左右偏移量
    offsets = ((1, 0), (-1, 0), (0, 1), (0, -1))

    day = 0

    # 如果扩散点没有了,或者所有点已被扩散,则停止循环
    while len(queue) > 0 and count > 0:
        newQueue = []

        for a, b in queue:
            for offsetX, offsetY in offsets:
                newX = a + offsetX
                newY = b + offsetY

                if 0 <= newX < m and 0 <= newY < n and matrix[newX][newY] == 0:
                    # 将点被扩散的时间记录为该点的值
                    matrix[newX][newY] = 1
                    # 被扩散到的点将变为新的扩散源
                    newQueue.append([newX, newY])
                    # 未被扩散点的数量--
                    count -= 1

        queue = newQueue
        day += 1

    return day


# 算法调用
print(getResult(m, n, i, j, x, y))

Java代码:

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
 
public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
 
    Integer[] arr =
        Arrays.stream(sc.next().split(",")).map(Integer::parseInt).toArray(Integer[]::new);
 
    System.out.println(getResult(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5]));
  }
 
  /**
   * @param m m m×n的二维数组
   * @param n n m×n的二维数组
   * @param i 扩散点位置为i,j
   * @param j 扩散点位置为i,j
   * @param k 扩散点位置为k,l
   * @param l 扩散点位置为k,l
   * @return 扩散所有点需要的时间
   */
  public static int getResult(int m, int n, int i, int j, int k, int l) {
    int[][] matrix = new int[m][n];
    matrix[i][j] = 1;
    matrix[k][l] = 1;
 
    // count记录未被扩散的点的数量
    int count = m * n - 2;
 
    // 多源BFS实现队列
    LinkedList<int[]> queue = new LinkedList<>();
    queue.addLast(new int[] {i, j});
    queue.addLast(new int[] {k, l});
 
    // 上下左右偏移量
    int[][] offsets = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
 
    int day = 0;
    // 如果扩散点没有了,或者所有点已被扩散,则停止循环
    while (queue.size() > 0 && count > 0) {
      LinkedList<int[]> newQueue = new LinkedList<>();
 
      for (int[] pos : queue) {
        int x = pos[0];
        int y = pos[1];
 
        for (int[] offset : offsets) {
          int newX = x + offset[0];
          int newY = y + offset[1];
 
          if (newX >= 0 && newX < m && newY >= 0 && newY < n && matrix[newX][newY] == 0) {
            // 将点被扩散的时间记录为该点的值
            matrix[newX][newY] = 1;
            // 被扩散到的点将变为新的扩散源
            newQueue.addLast(new int[] {newX, newY});
            // 未被扩散点的数量--
            count--;
          }
        }
      }
 
      queue = newQueue;
      day++;
    }
 
    return day;
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哇咔咔咔~

good good study

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

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

打赏作者

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

抵扣说明:

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

余额充值