(B卷,200分)- 矩阵扩散(Java & JS & Python & C)

题目描述

存在一个m×n的二维数组,其成员取值范围为0或1。

其中值为1的成员具备扩散性,每经过1S,将上下左右值为0的成员同化为1。

二维数组的成员初始值都为0,将第[i,j]和[k,l]两个个位置上元素修改成1后,求矩阵的所有元素变为1需要多长时间。

输入描述

输入数据中的前2个数字表示这是一个m×n的矩阵,m和n不会超过1024大小;

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

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

输出描述

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

用例

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

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

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

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

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

题目解析

用例图示如下:

 一共需要4-1=3秒。

本题可以使用图的多源BFS来解题。

关于图的多源BFS得解析,请看:

更多相关题目请看:

华为OD机试 – 污染水域_伏城之外的博客-CSDN博客

华为OD机试 – 计算网络信号、输出给定位置的信号强弱_伏城之外的博客-CSDN博客

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on("line", (line) => {
  const [m, n, i, j, k, l] = line.split(",").map(Number);
  console.log(getResult(m, n, i, j, k, l));
});

/**
 * @param {*} m m×n的二维数组
 * @param {*} n m×n的二维数组
 * @param {*} i 扩散点位置为i,j
 * @param {*} j 扩散点位置为i,j
 * @param {*} k 扩散点位置为k,l
 * @param {*} l 扩散点位置为k,l
 */
function getResult(m, n, i, j, k, l) {
  const matrix = new Array(m).fill(0).map(() => new Array(n).fill(0));
  matrix[i][j] = 1;
  matrix[k][l] = 1;

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

  // 多源BFS实现队列
  let queue = [
    [i, j],
    [k, l],
  ];

  // 上下左右偏移量
  const offsets = [
    [1, 0],
    [-1, 0],
    [0, 1],
    [0, -1],
  ];

  let day = 0;

  // 如果扩散点没有了,或者所有点已被扩散,则停止循环
  while (queue.length > 0 && count > 0) {
    const newQueue = [];

    for (const [x, y] of queue) {
      for (let [offsetX, offsetY] of offsets) {
        const newX = x + offsetX;
        const newY = y + offsetY;

        if (
          newX >= 0 &&
          newX < m &&
          newY >= 0 &&
          newY < n &&
          matrix[newX][newY] == 0
        ) {
          // 将点被扩散的时间记录为该点的值
          matrix[newX][newY] = 1;
          // 被扩散到的点将变为新的扩散源
          newQueue.push([newX, newY]);
          // 未被扩散点的数量--
          count--;
        }
      }
    }

    queue = newQueue;
    day++;
  }

  return day;
}

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;
  }
}

Python算法源码

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


# 算法入口
def getResult(m, n, i, j, k, l):
    """
    :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[k][l] = 1

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

    # 多源BFS实现队列
    queue = [[i, j], [k, l]]

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

    day = 0

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

        for x, y in queue:
            for offsetX, offsetY in offsets:
                newX = x + offsetX
                newY = y + 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, k, l))

C算法源码

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 1024

typedef struct ListNode {
    int ele;
    struct ListNode *next;
} ListNode;

typedef struct {
    int size;
    ListNode *head;
    ListNode *tail;
} LinkedList;

LinkedList *new_LinkedList();
void addLast_LinkedList(LinkedList *link, int ele);

int matrix[MAX_SIZE][MAX_SIZE] = {0};

int main() {
    int m, n, i, j, k, l;
    scanf("%d,%d,%d,%d,%d,%d", &m, &n, &i, &j, &k, &l);

    // 初始扩散点位置为i,j
    matrix[i][j] = 1;
    // 初始扩散点位置为k,l
    matrix[k][l] = 1;

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

    // 多源BFS实现队列
    LinkedList *queue = new_LinkedList();
    addLast_LinkedList(queue, i * n + j);
    addLast_LinkedList(queue, k * n + l);

    // 上下左右偏移量
    int offsets[4][2] = {{1,  0},
                         {-1, 0},
                         {0,  1},
                         {0,  -1}};

    // 扩散时间
    int day = 0;

    // 如果扩散点没有了,或者所有点已被扩散,则停止循环
    while (queue->size > 0 && count > 0) {
        LinkedList *newQueue = new_LinkedList();

        ListNode *cur = queue->head;
        while (cur != NULL) {
            int x = cur->ele / n;
            int y = cur->ele % n;

            for (int a = 0; a < 4; a++) {
                int newX = x + offsets[a][0];
                int newY = y + offsets[a][1];

                if (newX >= 0 && newX < m && newY >= 0 && newY < n && matrix[newX][newY] == 0) {
                    // 将点被扩散的时间记录为该点的值
                    matrix[newX][newY] = 1;
                    // 被扩散到的点将变为新的扩散源
                    addLast_LinkedList(newQueue, newX * n + newY);
                    // 未被扩散点的数量--
                    count--;
                }
            }
            cur = cur->next;
        }

        queue = newQueue;
        day++;
    }

    printf("%dn", day);

    return 0;
}

LinkedList *new_LinkedList() {
    LinkedList *link = (LinkedList *) malloc(sizeof(LinkedList));

    link->size = 0;
    link->head = NULL;
    link->tail = NULL;

    return link;
}

void addLast_LinkedList(LinkedList *link, int ele) {
    ListNode *node = (ListNode *) malloc(sizeof(ListNode));

    node->ele = ele;
    node->next = NULL;

    if (link->size == 0) {
        link->head = node;
        link->tail = node;
    } else {
        link->tail->next = node;
        link->tail = node;
    }

    link->size++;
}

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?