华为OD机考算法题:计算疫情扩散时间

news/2024/7/20 17:27:19 标签: 华为od, 算法, 数据结构, Java, javascript

题目部分

题目计算疫情扩散时间
难度
题目说明在一个地图中(地图由 n * n 个区域组成)有部分区域被感染病菌感染区域每天都会把周围(上下左右)的4个区域感染。
请根据给定的地图计算多少天以后,全部区域都会被感染。
如果初始地图上所有区域全部都被感染,或者没有被感染区域,返回-1。
输入描述一行 N * N 个数字(只包合 0、1,不会有其他数字)表示一个地图,数字间用分割,0 表示未感染区域,1 表示已经感染区域每 N 个数字表示地图中一行,输入数据共表示 N 行 N 列的区域地图。
例如输入1,0,1,0,0,0,1,0,1,表示地图
1,0,1
0,0,0
1,0,1
输出描述一个整数,表示经过多少天以后,全部区域都被感染。
补充说明1 <= N < 200。
------------------------------------------------------
示例
示例1
输入1,0,1,0,0,0,1,0,1
输出2
说明1 天之后,地图上仅剩中心点未被感染;2 天之后,全部被感染。
示例2
输入0,0,0,0
输出-1
说明无感染区域
示例3
输入1,1,1,1,1,1,1,1,1
输出-1
说明已经全部被感染


解读与分析

题目解读

给定一个一维数组,数组中的数字为 0、1,把它转换成对应的二维数组。如果数组的初始值全为 0 或全为 1,返回 -1。每一天,数字为 1 的会把其上下左右 4 个方向的值改成 1。求多少天后,全部都变成 1。

分析与思路

实现机制比较简单,先解析输入数据,接着统计 0 和 1 的数字,之后把 1 上下左右的数字变成 1,再统计,直到所有的数据都变成 1。具体实现步骤如下:
1. 解析数据。把输入数据解析成一维数组,记录所有包含 1 的数组下标。
2. 统计。如果 1 的个数等于所有数字个数,或 1 的个数为 0,返回 -1。否则,进行第 3 步。
3. 初始换当前感染数据。
把所有值为 1 的数字下标放到集合中,设为 value1Set。
4. 更新感染数字。遍历 value1Set,计算当天之后所有值为 1 的下标,放到集合 newValue1Set中。当前天数加1。
5. 统计 newValue1Set 的元素个数,如果等于全部个数,则全部感染,返回当前天数。否则,把 newValue1Set 赋值给 value1Set,继续执行步骤 4。

此方法的时间复杂度为 O( n平方 ),空间复杂度为 O(n)。


代码实现

Java代码

import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
 * 计算疫情扩散时间
 * 
 * @since 2023.11.01
 * @version 0.1
 * @author Frank
 *
 */
public class DiseaseSpread {

    public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	while (sc.hasNext()) {
	    String input = sc.nextLine();
	    String[] inputArr = input.split(",");

	    int arrCount = inputArr.length;
	    Set<Integer> diseaseSet = new HashSet<Integer>();
	    for (int i = 0; i < arrCount; i++) {
		int value = Integer.parseInt(inputArr[i]);
		if (value == 1) {
		    diseaseSet.add(i);
		}
	    }
	    processDiseaseSpread(arrCount, diseaseSet);

	}

    }

    private static void processDiseaseSpread(int arrCount, Set<Integer> diseaseSet) {
	if (diseaseSet.size() == 0 || diseaseSet.size() == arrCount) {
	    System.out.println(-1);
	    return;
	}
	int days = 0;
	// 避免误差,使用 Math.round。
	int dimension = (int) Math.round(Math.sqrt(arrCount));

	Set<Integer> newDiseaseSet = new HashSet<Integer>();
	newDiseaseSet.addAll(diseaseSet);

	while (diseaseSet.size() != arrCount) {
	    for (Iterator<Integer> iter = diseaseSet.iterator(); iter.hasNext();) {
		int coords = iter.next();
		updateNewCoords(dimension, coords, newDiseaseSet);
	    }
	    days++;
	    if (newDiseaseSet.size() == arrCount) {
		System.out.println(days);
		return;
	    }
	    diseaseSet = newDiseaseSet;
	}

    }

    private static void updateNewCoords(int dimension, int coords, Set<Integer> newDiseaseSet) {
	int i = coords / dimension;
	int j = coords % dimension;

	int[][] fourDirections = { { i, j - 1 }, { i, j + 1 }, { i - 1, j }, { i + 1, j } };
	for (int k = 0; k < fourDirections.length; k++) {
	    int curI = fourDirections[k][0];
	    int curJ = fourDirections[k][1];
	    if (curI < 0 || curJ < 0 || curI >= dimension || curJ >= dimension) {
		continue;
	    }
	    Integer curCoords = curI * dimension + curJ;
	    if (!newDiseaseSet.contains(curCoords)) {
		newDiseaseSet.add(curCoords);
	    }
	}

    }

}

JavaScript代码

javascript">const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void async function() {
    while (line = await readline()) {

        var inputArr = line.split(",");
        var arrCount = inputArr.length;

        var diseaseSet = new Set();
        for (var i = 0; i < arrCount; i++) {
            var value = parseInt(inputArr[i]);
            if (value == 1) {
                diseaseSet.add(i);
            }
        }
        processDiseaseSpread(arrCount, diseaseSet);
    }
}();

function processDiseaseSpread(arrCount, diseaseSet) {
    if (diseaseSet.size == 0 || diseaseSet.size == arrCount) {
        console.log(-1);
        return;
    }
    var days = 0;
    // 避免误差,使用 Math.round。
    var dimension = Math.round(Math.sqrt(arrCount));
    while (diseaseSet.size != arrCount) {
        var newDiseaseSet = new Set();
        for (var i of diseaseSet) {
            newDiseaseSet.add(i);
            updateNewCoords(dimension, i, newDiseaseSet);
        }

        days++;
        if (newDiseaseSet.size == arrCount) {
            console.log(days);
            return;
        }
        diseaseSet = newDiseaseSet;
    }
}

function updateNewCoords(dimension, coords, newDiseaseSet) {
    var i = parseInt(coords / dimension);
    var j = coords % dimension;

    var fourDirections = [
        [i, j - 1],
        [i, j + 1],
        [i - 1, j],
        [i + 1, j]
    ];
    for (var k = 0; k < fourDirections.length; k++) {
        var curI = fourDirections[k][0];
        var curJ = fourDirections[k][1];
        if (curI < 0 || curJ < 0 || curI >= dimension || curJ >= dimension) {
            continue;
        }
        var curCoords = curI * dimension + curJ;
        if (!newDiseaseSet.has(curCoords)) {
            newDiseaseSet.add(curCoords);
        }
    }

}

(完)


http://www.niftyadmin.cn/n/5143318.html

相关文章

mathtype最新7.4.10.53绿色版本下载

MathType&#xff0c;一款功能强大的数学公式编辑器&#xff0c;一直深受广大用户的喜爱&#xff0c;给很多的理科生和各位学者、教研机构等带来巨大帮助。 软件的主要使用用户为初中、高中以及大学的学生、老师&#xff0c;理工科专业工作者&#xff0c;可用于编辑数学试卷、…

【Linux】vim 使用

目录 一&#xff0c;vim 与 vi 1&#xff0c;vim 的基本概念 二&#xff0c;vim 的基本操作 三&#xff0c;vim 正常模式命令集 1&#xff0c;插入模式 2&#xff0c;从插入模式或者底行模式切换为命令模式 3&#xff0c;移动光标 4&#xff0c;删除文字 5&#xff0…

python常见问题及解决

一、安装第三方库 1、安装paramiko报错&#xff0c;[错误记录]paramiko模块错误&#xff1a;from_buffer() cannot return the address of the raw string 先执行python -m pip install --no-use-pep517 bcrypt&#xff0c;再执行pip install paramiko pip install --upgrad…

【论文分享】Exploring Security Commits in Python

Title: Exploring Security Commits in Python (探索Python中的安全提交) Authors: Shiyu Sun, Shu Wang, Xinda Wang, Yunlong Xing, Elisa Zhang, Kun Sun Affiliation: George Mason University (乔治梅森大学) Keywords: Security Commit, Python, Dataset Construction…

优优嗨聚集团:医保新政来袭,乙类OTC、保健品或将退出医保舞台,影响几何?

近日&#xff0c;国家医保局发布征求意见稿&#xff0c;拟将乙类OTC&#xff08;非处方药&#xff09;和保健品从医保目录中移除。这一政策一旦实施&#xff0c;无疑将对广大参保人员和相关企业产生深远影响。本文将为您详细解析这一政策可能带来的影响&#xff0c;以及如何应对…

电脑开机显示器不亮?正确操作分享(4个方法)!

“我的电脑最近不知道为什么&#xff0c;每次开机后显示器都不亮&#xff0c;重启也没反应&#xff0c;有什么方法可以解决该问题吗&#xff1f;快帮帮我&#xff01;” 随着电脑在我们日常生活和工作中的广泛应用&#xff0c;出现问题时需要及时解决。在众多的电脑问题中&…

Vue:实现复制按钮功能

作者:CSDN @ _乐多_ 本文记录了vue开发中,复制按钮的实现代码。用于复制网页中的一个数或者字符串啥的。 效果如下图所示, 文章目录 <el-button @click="copyToClipboard(wgs84Position2.altitude)">复制</el-button>data(

Selenium学习(Java + Edge)

Selenium /səˈliːniəm/ 1. 简介 ​ Selenium是一个用于Web应用程序自动化测试工具。Selenium测试直接运行在浏览器中&#xff0c;就像真正的用户在操作一样。支持的浏览器包括IE、Mozilla Firefox、Safari、Google Chrome、Opera、Edge等。 ​ 适用于自动化测试&#x…