华为OD机考算法题:开心消消乐

news2024/11/28 13:44:04

题目部分

题目开心消消乐
难度
题目说明给定一个 N 行 M 列的二维矩阵,矩阵中每个位置的数字取值为 0 或 1,矩阵示例如:
1 1 0 0
0 0 0 1
0 0 1 1
1 1 1 1
现需要将矩阵中所有的 1 进行反转为 0,规则如下:
1) 当点击一个 1 时,该 1 被反转为 0,同时相邻的上、下、左、右,以及左上、左下、右上、右下 8 个方向的 1 (如果存在 1)均会自动反转为 0;
2) 进一步地,一个位置上的 1 被反转为 0 时,与其相邻的 8 个方向的 1 (如果存在 1)均会自动反转为 0; 按照上述规则示例中的矩阵只最少需要点击 2 次后,所有均值 0 。请问,给定一个矩阵,最少需要点击几次后,所有数字均为 0?
输入描述第一行输入两个整数,分别表示矩阵的行数 N 和列数 M,取值范围均为 [1,100] 接下来 N 行表示矩阵的初始值,每行均为 M 个数,取值范围 [0,1]。
输出描述输出一个整数,表示最少需要点击的次数。
补充说明
------------------------------------------------------
示例
示例1
输入3 3
1 0 1
0 1 0
1 0 1
输出1
说明上述样例中,四个角上的 1 均在中间的 1 的相邻 8 个方向上,因此只需要点击一次即可。
示例2
输入

4 4
1 1 0 0
1 0 0 0
0 0 0 1
0 0 1 1 

输出2
说明在上述 4 * 4 的矩阵中,只需要点击 2 次(左上角 和 右下角),即可将所有的 1 消除。


解读与分析

题目解读

点击一个 1,它相邻八个方向的 1 变成 0,与此同时,这八个方向如果存在 1 变成 0,那么与它相邻的八个方向的 1 也会变成 0。

有点像扫雷游戏。

分析与思路

此题可以采用广度优先搜索或深度优先搜索,遍历所有点击的情况。然后根据所有点击情况,计算出最小的点击次数。

时间复杂度为 O(n^{2}),空间复杂度为 O(n^{2})。

与《华为OD机考算法题:机器人活动区域》有些类似。


代码实现

Java代码

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

/**
 * 开心消消乐
 * 
 * @since 2023.10.13
 * @version 0.2
 * @author Frank
 *
 */
public class HappyCollapse {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			String line = sc.nextLine();
			String[] rc = line.split(" ");
			int row = Integer.parseInt(rc[0]);
			int column = Integer.parseInt(rc[1]);

			int[][] matrix = new int[row][column];
			for (int i = 0; i < row; i++) {
				line = sc.nextLine();
				String[] strColumnValue = line.split(" ");
				int[] number = new int[column];
				for (int j = 0; j < column; j++) {
					number[j] = Integer.parseInt(strColumnValue[j]);
				}
				matrix[i] = number;
			}

			processHappyCollapse(matrix, row, column);
		}

	}

	static class Node {
		int i;
		int j;

		public Node(int i, int j) {
			this.i = i;
			this.j = j;
		}

		@Override
		public int hashCode() {
			return (i + " " + j).hashCode();
		}

		@Override
		public boolean equals(Object obj) {
			if (!(obj instanceof Node))
				return false;
			Node node = (Node) obj;
			return node.i == i && node.j == j;
		}
	}

	private static void processHappyCollapse(int[][] matrix, int row, int column) {
		Set<Node> nodeSet = new HashSet<Node>();
		List<Node> nodeList = new ArrayList<Node>();
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				if (matrix[i][j] == 1) {
					Node node = new Node(i, j);
					nodeList.add(node);

					nodeSet.add(node);
				}
			}
		}

		int[] rowColumn = new int[2];
		rowColumn[0] = row;
		rowColumn[1] = column;

		int minCnt = Integer.MAX_VALUE;
		for (int i = 0; i < nodeList.size(); i++) {
			List<Node> copyOfList = new ArrayList<Node>();
			copyOfList.addAll(nodeList);

			Set<Node> copyOfSet = new HashSet<Node>();
			copyOfSet.addAll(nodeSet);

			Node node = nodeList.get(i);

			copyOfList.remove(i);
			copyOfSet.remove(node);

			int cnt = startClickNode(node, copyOfList, copyOfSet, rowColumn);
			if (cnt < minCnt) {
				minCnt = cnt;
			}
		}
		System.out.println(minCnt);

	}

	private static int startClickNode(Node node, List<Node> nodeList, Set<Node> nodeSet, int[] rowColumn) {
		int clickCnt = 1;
		clickCollapseNode(node, nodeList, nodeSet, rowColumn);

		if (nodeList.size() == 0) {
			return 1;
		}

		int minCnt = Integer.MAX_VALUE;
		for (int i = 0; i < nodeList.size(); i++) {
			List<Node> copyOfList = new ArrayList<Node>();
			copyOfList.addAll(nodeList);

			Set<Node> copyOfSet = new HashSet<Node>();
			copyOfSet.addAll(nodeSet);

			Node curNode = nodeList.get(i);

			copyOfList.remove(i);
			copyOfSet.remove(curNode);

			int cnt = startClickNode(curNode, copyOfList, nodeSet, rowColumn);
			if (cnt < minCnt) {
				minCnt = cnt;
			}

		}
		return clickCnt + minCnt;
	}

	private static void clickCollapseNode(Node node, List<Node> nodeList, Set<Node> nodeSet, int[] rowColumn) {
		int row = rowColumn[0];
		int column = rowColumn[1];

		if (node.i >= 1) {
			colapseNode(new Node(node.i - 1, node.j), nodeList, nodeSet, rowColumn);
		}
		if (node.i < row - 1) {
			colapseNode(new Node(node.i + 1, node.j), nodeList, nodeSet, rowColumn);
		}
		if (node.j >= 1) {
			colapseNode(new Node(node.i, node.j - 1), nodeList, nodeSet, rowColumn);
		}
		if (node.j < column - 1) {
			colapseNode(new Node(node.i, node.j + 1), nodeList, nodeSet, rowColumn);
		}
		if (node.i >= 1 && node.j >= 1) {
			colapseNode(new Node(node.i - 1, node.j - 1), nodeList, nodeSet, rowColumn);
		}
		if (node.i >= 1 && node.j < column - 1) {
			colapseNode(new Node(node.i - 1, node.j + 1), nodeList, nodeSet, rowColumn);
		}
		if (node.i < row - 1 && node.j >= 1) {
			colapseNode(new Node(node.i + 1, node.j - 1), nodeList, nodeSet, rowColumn);
		}
		if (node.i < row - 1 && node.j < column - 1) {
			colapseNode(new Node(node.i - 1, node.j + 1), nodeList, nodeSet, rowColumn);
		}
	}

	private static void colapseNode(Node node, List<Node> nodeList, Set<Node> nodeSet, int[] rowColumn) {
		if (nodeSet.contains(node)) {
			nodeList.remove(node);
			nodeSet.remove(node);
			clickCollapseNode(node, nodeList, nodeSet, rowColumn);
		}
	}

}

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 rowColumn = line.split(" ");
        var row = parseInt(rowColumn[0]);
        var column = parseInt(rowColumn[1]);

        var matrix = new Array();
        for (var i = 0; i < row; i++) {
            line = await readline();
            var strNumbers = line.split(" ");
            var numbers = new Array(column);
            for (var j = 0; j < column; j++) {
                numbers[j] = parseInt(strNumbers[j]);
            }
            matrix[i] = numbers;
        }

        processHappyCollapse(matrix, row, column);
    }
}();

function processHappyCollapse(matrix, row, column) {
    var nodeSet = new Set();
    var nodeList = new Array();
    for (var i = 0; i < row; i++) {
        for (var j = 0; j < column; j++) {
            if (matrix[i][j] == 1) {
                var node = i + "," + j;
                nodeList.push(node);
                nodeSet.add(node);
            }
        }
    }

    var rowColumn = new Array();
    rowColumn[0] = row;
    rowColumn[1] = column;

    var minCnt = Number.MAX_VALUE;
    for (var i = 0; i < nodeList.length; i++) {
        var copyOfList = Array.from(nodeList);
        var copyOfSet = new Set(nodeSet);

        var node = nodeList[i];

        copyOfList.splice(i, 1);
        copyOfSet.delete(node);

        var cnt = startClickNode(node, copyOfList, copyOfSet, rowColumn);
        if (cnt < minCnt) {
            minCnt = cnt;
        }
    }
    console.log(minCnt);
}

function startClickNode(node, nodeList, nodeSet, rowColumn) {
    var clickCnt = 1;
    clickCollapseNode(node, nodeList, nodeSet, rowColumn);

    if (nodeList.length == 0) {
        return 1;
    }

    var minCnt = Number.MAX_VALUE;
    for (var i = 0; i < nodeList.length; i++) {
        var copyOfList = Array.from(nodeList);
        var copyOfSet = new Set(nodeSet);

        var curNode = nodeList[i];

        copyOfList.splice(i, 1);
        copyOfSet.delete(curNode);

        var cnt = startClickNode(curNode, copyOfList, nodeSet, rowColumn);
        if (cnt < minCnt) {
            minCnt = cnt;
        }
    }
    return clickCnt + minCnt;
}

function clickCollapseNode(node, nodeList, nodeSet, rowColumn) {
    var row = rowColumn[0];
    var column = rowColumn[1];

    var nodeStrValue = node.split(",");
    var nodeValue = new Array();
    nodeValue[0] = parseInt(nodeStrValue[0]);
    nodeValue[1] = parseInt(nodeStrValue[1]);

    for (var i = -1; i <= 1; i++) {
        if (nodeValue[0] + i < 0 || nodeValue[0] + i > row - 1) {
            continue;
        }
        for (var j = -1; j <= 1; j++) {
            if (i == 0 && j == 0) {
                continue;
            }
            if (nodeValue[1] + j < 0 || nodeValue[1] + j > column - 1) {
                continue;
            }
            colapseNode((nodeValue[0] + i) + "," + (nodeValue[1] + j), nodeList, nodeSet, rowColumn);
        }
    }

}

function colapseNode(node, nodeList, nodeSet, rowColumn) {
    if (nodeSet.has(node)) {
        var idx = nodeList.indexOf(node);
        nodeList.splice(idx, 1);
        nodeSet.delete(node);
        clickCollapseNode(node, nodeList, nodeSet, rowColumn);
    }
}

虽然此题的难度标记为“易”,实际编码量比较大。难度并不小,在短时间内写出代码并不是很容易。

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1096469.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

互联网Java工程师面试题·Java 总结篇·第一弹

目录 1、面向对象的特征有哪些方面&#xff1f; 2、访问修饰符 public,private,protected,以及不写&#xff08;默认&#xff09;时的区别&#xff1f; 3、String 是最基本的数据类型吗&#xff1f; 4、float f3.4;是否正确&#xff1f; 5、short s1 1; s1 s1 1;有错吗…

Deno 下一代JavaScript运行时

目录 1、简介 2、Deno 的特点 3、Deno 和 Node 的区别 4、TypeScript开箱即用 5、内置的基本开发工具 独立可执行文件 测试运行器 代码格式化程序 代码linter 6、专为云而建 7、从浏览器到后端的一致代码 TC39 WinterCG 8、高性能联网 9、数百万个社区模块 10、相关框架 1、简介…

Stream流中的 distinct()方法

去除流中重要的元素。依赖&#xff08;hashCode和equals方法&#xff09; Stream流中无法直接修改集合、数组中的数据 package com.csdn.streampractice; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class StreamTest {public …

初级篇—第八章精讲MySQL数据类型

文章目录 MySQL数据类型常见的属性字符集设置数据库的字符设置表的字符集设置字段的字符集设置 整型数据类型可选属性MUNSIGNEDZEROFILL 如何选择&#xff1f; 浮点类型FLOAT 和 DOUBLE 这两种数据类型的区别是啥呢&#xff1f;为什么浮点数类型的无符号数取值范围&#xff0c;…

使用js获取选中的dom元素 并改变选中(有序dom)的状态

一个效果图&#xff0c;一段代码&#xff0c; 就这样吧。 <template><!-- <el-checkbox v-model"">开启双向</el-checkbox> --><divref"checkListRef"mouseup"mouseupCon"mousedown"mousedownCon"mouseov…

【MySQL】深入了解索引的底层逻辑结构

文章目录 主键排序一. InnoDB的索引结构1. 单个page2. 多个page 二. 为什么选择B树三. 聚簇索引和非聚簇索引结束语 主键排序 我们创建一个user表&#xff0c;并乱序插入数据 mysql> create table if not exists user(-> id int primary key,-> age int not null,-&…

【AI视野·今日NLP 自然语言处理论文速览 第五十四期】Fri, 13 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Fri, 13 Oct 2023 Totally 75 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Tree-Planner: Efficient Close-loop Task Planning with Large Language Models Authors Mengkang Hu, Yao M…

比特听命:补码的产生过程与整数在计算机中的存储

文章目录 参考环境声明八位二进制加法器八进制数值 原码概念正负数与零正数与负数的运算 反码概念一步之遥 补码概念唯一的零加法运算 补码的优缺点优点简化算术运算一眼辨别正负性运算过程中无需对符号位进行处理 缺点不易阅读 参考 项目描述搜索引擎Bing、GoogleAI 大模型文…

c#设计模式-行为型模式 之 访问者模式

&#x1f680;简介 封装一些作用于某种数据结构中的各元素的操作&#xff0c;它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。 访问者模式包含以下主要角色 : 抽象访问者&#xff08;Visitor&#xff09;角色&#xff1a;定义了对每一个元素 &#xff08;E…

英语——语法——从句——句型和句子成分——笔记

老师导言&#xff1a;易于理解。 三种句型&#xff1a;1、主系表&#xff1b;2.主谓*&#xff1b;3.there be 句型&#xff1a;句子构成的形式。句子用于相互沟通&#xff0c;需要表达自己意思&#xff0c;句子中就存在一个主语&#xff0c;一般对主语&#xff08;主要描述对象…

4.Mask R-CNN/YOLOV8/RTMDET三种实例分割方法推理逻辑对比

文章目录 Mask R-CNN/YOLOV8/RTMDET三种实例分割方法推理逻辑对比Mask R-CNNYOLOV5/8实例分割方法RTMDet中的实例分割 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; Mask R-CNN/YOLOV8/RTMDET三种实例分割方法推理逻辑对比 实例分割是同…

CLIP模型原理与代码实现详解

文章目录 前言一、CLIP模型原理1.背景介绍2.对比训练方式3.prompt推理方式4.图像与文本编码结构5.特征CLS token结构vit划分patch原理cls token原理 二、CLIP环境安装1.官方环境安装2.CLIP环境安装3.CLIP运行结果 三.CLIP的Transformer结构代码解读四、CLIP模型主函数代码解读五…

相似性搜索:第 4 部分--分层可导航小世界 (HNSW)

SImilarity 搜索是一个问题&#xff0c;给定一个查询的目标是在所有数据库文档中找到与其最相似的文档。 一、介绍 在数据科学中&#xff0c;相似性搜索经常出现在NLP领域&#xff0c;搜索引擎或推荐系统中&#xff0c;其中需要检索最相关的文档或项目以进行查询。在大量数据中…

从0开始学go第八天

gin获取URL路径参数 package main//获取path&#xff08;URL&#xff09;参数 import ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/:name/:age", func(c *gin.Context) {//获取路径参数name : c.Param(&quo…

15 | JPA 对 Web MVC 开发者做了哪些支持

我们使用 Spring Data JPA 的时候&#xff0c;一般都会用到 Spring MVC&#xff0c;Spring Data 对 Spring MVC 做了很好的支持&#xff0c;体现在以下几个方面&#xff1a; 支持在 Controller 层直接返回实体&#xff0c;而不使用其显式的调用方法&#xff1b;对 MVC 层支持标…

如何通过Photoshop将视频转换成GIF图片

一、应用场景 1、将视频转有趣动图发朋友圈 2、写CSDN无法上传视频&#xff0c;而可以用GID动图替代 3、其他 二、实现步骤 1、打开Photoshop APP 2、点击文件——导入——视频帧到图层 3、选择视频文件 4、配置视频信息&#xff0c;按照图片提示配置完毕之后&#xff0c;…

gma 2.0.2 (2023.10.15) 更新日志

安装 gma 2.0.2 pip install gma2.0.2新增 0.1、矢量提取&#xff08;重要更新&#xff09; &#xff08;见简单示例&#xff09;   现在&#xff0c;你可以像 numpy 或 pandas 一样直接对 Layer 进行切片提取。 0.2、修改属性表&#xff08;重要更新&#xff09; &#xff…

数电第一次实验

四选一&#xff0c;信号选择器 三位4选1多路选择器 要求输入信号有4个&#xff0c;且每个信号宽3位 如果是直接根据选择信号选 选择的是信号&#xff0c;选择的是编号&#xff0c;与信号具体是什么内容无关&#xff0c;信号的内容与其是否被选择无关&#xff0c;信号的编号…

E034-服务漏洞利用及加固-利用CVE-2016-5195漏洞实现Linux系统本地提权

实验等级: 中级 任务场景: 【任务场景】 小王接到磐石公司的邀请&#xff0c;对该公司内部网络进行渗透测试&#xff0c;经过对局域网被操作系统进行全面的维护中&#xff0c;发现了一台内核版本为4.2.0-27的Linux服务器&#xff0c;低权限用户利用该漏洞技术可以在全版本L…

【笔记整理】软考-软件设计师

一、计算机系统 计算机基本单位 单位名称简称换算位bitb字节byteB1B8b千字节KB1KB1024B兆字节MB1MB1024KB吉字节GB1GB1024MB太字节TB1TB1024GB 带宽单位Mbps的b是指Bit&#xff08;位&#xff09; 速度单位MB/s的B是指Byte&#xff08;字节&#xff09; 1MB/s&#xff1d;8M…