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

题目部分

题目开心消消乐
难度
题目说明给定一个 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;}@Overridepublic int hashCode() {return (i + " " + j).hashCode();}@Overridepublic 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.mzph.cn/news/106540.shtml

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

相关文章

动态规划算法(3)--0-1背包、石子合并、数字三角形

目录 一、0-1背包 1、概述 2、暴力枚举法 3、动态规划 二、石子合并问题 1、概述 2、动态规划 3、环形石子怎么办&#xff1f; 三、数字三角形问题 1、概述 2、递归 3、线性规划 四、租用游艇问题 一、0-1背包 1、概述 0-1背包&#xff1a;给定多种物品和一个固定…

ChatGPT,AIGC 数据库应用 Mysql 常见优化30例

使用ChatGPT,AIGC总结出Mysql的常见优化30例。 1. 建立合适的索引:在Mysql中,索引是重要的优化手段,可以提高查询效率。确保表的索引充分利用,可以减少查询所需的时间。如:create index idx_name on table_name(column_name); 2. 避免使用select * :尽可能指定要返回的…

HTML笔记

注释标签&#xff1a;<!-- --> 标题标签&#xff1a;&#xff08;作用范围依次递减&#xff09; <h1></h1> <h2></h2> <h3></h3> <h4></h4> <h5></h5> <h6></h6> 段落标签&#xff1a;<p&g…

抖音开放平台第三方代小程序开发,授权事件、消息与事件通知总结

大家好&#xff0c;我是小悟 关于抖音开放平台第三方代小程序开发的两个事件接收推送通知&#xff0c;是开放平台代小程序实现业务的重要功能。 授权事件推送和消息与事件推送类型都以Event的值判断。 授权事件推送通知 授权事件推送包括&#xff1a;推送票据、授权成功、授…

智能油烟机 优化烹饪体验

如果说空调是夏天最伟大的发明&#xff0c;那么油烟机则是健康厨房的伟大推进者。随着科技的发展&#xff0c;智能化的油烟机逐渐走进了人们的日常生活。每当我们在爆炒、油炸食物的时候&#xff0c;油烟总能呛得人眼睛痛、鼻子难受&#xff0c;传统的油烟机面前我们还需要手动…

vue3后台管理框架之路由配置

pnpm install vue-router 在src新建文件夹views和router 1.1基本 路由配置 :hash 路由模式 // 对外配置路由 import Login from @/views/login/index.vue import Home from @/views/home/index.vue import Error from @/views/404/index.vue export cons

JavaScript基础知识13——运算符:一元运算符,二元运算符

哈喽&#xff0c;大家好&#xff0c;我是雷工。 JavaScript的运算符可以根据所需表达式的个数&#xff0c;分为一元运算符、二元运算符、三元运算符。 一、一元运算符 1、一元运算符&#xff1a;只需要一个表达式就可以运算的运算符。 示例&#xff1a;正负号 一元运算符有两…

英语——歌曲篇——All Out Of Love

All Out Of Love [Air Supply失落的爱] 歌词 I’m lying alone with my head on the phone Thinking of you till it hurts I know you hurt too but what else can we do Tormented and torn apart I wish I could carry your smile in my heart For times when my life se…

自动驾驶学习笔记(五)——绕行距离调试

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 调试内容 打开在线编辑器 打开pl…

基础算法:二分查找

目录 1. 二分查找2. 补充&#xff1a;二进制运算2.1 十进制与二进制的相互转换2.1.1 十进制转二进制2.1.2 二进制转十进制 2.2 机器数 真值2.3 原码 补码 反码2.4 二进制的加减乘除2.5 移位运算 1. 二分查找 思想&#xff1a; 有序数组&#xff0c;从中找值 实现&#xff1a;…

IDEA报Error:java:无效的源发行版13解决方式

出现问题原因&#xff1a;原本项目是spingboot2.0版本开发的&#xff0c;IDEA启动正常&#xff0c;后期新项目使用spingboot3.0&#xff0c;通过原来的IDEA版本及JDK1.8启动报上述错误&#xff0c;以下为版本文件 解决方式&#xff1a; 项目背景&#xff1a;项目已经上线&…

因为写保护,U盘会“假死”。如何在Windows 10上删除写保护

本文介绍如何从USB驱动器、SD卡或单个文件中删除写保护。说明适用于Windows 10、Windows 8和Windows 7。 如何使用锁定开关解除写保护 如果你的计算机告诉你介质受写保护&#xff0c;请在USB或SD卡上查找写保护开关&#xff08;也称为锁定开关&#xff09;。如果介质有此开关…

中断机制-通过volatile实现线程中断停止

4.1.4 大厂面试题中断机制考点 如何停止中断运行中的线程&#xff1f; 通过一个volatile变量实现 package com.nanjing.gulimall.zhouyimo.test;import java.util.concurrent.TimeUnit;/*** author zhou* version 1.0* date 2023/10/15 2:34 下午*/ public class InterruptD…

JS DataTable中导出PDF右侧列被截断的问题解决

JS DataTable中导出PDF右侧列被截断的问题解决 文章目录 JS DataTable中导出PDF右侧列被截断的问题解决一. 问题二. 解决办法三. 代码四. 参考资料 一. 问题 二. 解决办法 设置PDF大小和版型 orientation: landscape, pageSize: LEGAL,上述代码设置打印的PDF尺寸为LEGAL&…

深入理解 JVM(重点:双亲委派模型 + 垃圾回收算法)

一、什么是 JVM&#xff1f; JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java虚拟机。虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。可以认为 JVM 是一台被定制过的现实当中不存在的计算机&#xff0c;Java程序最终是…

Android---Android 是如何通过 Activity 进行交互的

相信对于 Android 工程师来说&#xff0c;startActivity 就像初恋一般。要求低&#xff0c;见效快&#xff0c;是每一个菜鸟 Android 工程师迈向高级 Android 工程师的必经阶段。经过这么多年的发展&#xff0c;startActivity 在 google 的调教下已经变得愈发成熟&#xff0c;对…

【Express】服务端渲染(模板引擎 EJS)

EJS&#xff08;Embedded JavaScript&#xff09;是一款流行的模板引擎&#xff0c;可以用于在Express中创建动态的HTML页面。它允许在HTML模板中嵌入JavaScript代码&#xff0c;并且能够生成基于数据的动态内容。 下面是一个详细的讲解和示例&#xff0c;演示如何在Express中…

Mac安装Kali保姆级教程

Mac安装Kali保姆级教程 其他安装教程&#xff1a;使用VMware安装系统Window、Linux&#xff08;kali&#xff09;、Mac操作系统 1 虚拟机安装VM Fusion 去官网下载VM Fusion 地址&#xff1a;https://customerconnect.vmware.com/en/evalcenter?pfusion-player-personal-13 …

网工记背配置命令(3)----POE配置示例

POE 供电就是通过以太网供电&#xff0c;这种方式仅凭借那根连接通信终端的网线就可完成为它们供电。POE提供的是-53V~0v 的直流电&#xff0c;供电距离最长可达 100m。PoE 款型的交换机的软件大包天然支持 POE&#xff0c;无需 license&#xff0c;通过执行 poe-enable 命令使…

Android 10.0 禁止弹出系统simlock的锁卡弹窗功能实现

1.前言 在10.0的系统开发中,在一款产品中,需要实现simlock锁卡功能,在系统实现锁卡功能以后,在开机的过程中,或者是在插入sim卡 后,当系统检测到是禁用的sim卡后,就会弹出simlock锁卡弹窗,要求输入puk 解锁密码,功能需求禁用这个弹窗,所以就需要看是 哪里弹的,禁用…