华为OD机试真题 - 矩阵匹配 - 深度优先搜索DFS(Python/JS/C/C++ 2024 D卷 200分)

news2024/9/19 15:36:03

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

从一个 N×M(N≤M)的矩阵中选出 N 个数,任意两个数字不能在同一行或同一列,求选出来的 N 个数中第 K 大的数字的最小值是多少。

二、输入描述

输入矩阵要求: 1≤K≤N≤M≤150

输入格式:

N M K
N*M矩阵

三、输出描述

N×M 的矩阵中可以选出 M!/N!种组合数组,每个组合数组种第 K 大的数中的最小值。无需考虑重复数字,直接取字典排序结果即可。

备注:

注意:结果是第 K 大的数字的最小值

四、测试用例

测试用例1:

1、输入

3 3 2
2 1 4
5 3 7
9 6 8

2、输出

3

测试用例2:

1、输入

3 4 2
1 5 6 6
8 3 4 3
6 8 6 3

2、输出

3

3、说明

第一行:[2, 3, 4],第2大的数是3
第二行:[1, 5, 6, 6],第2大的数是6
第三行:[3, 3, 4, 8],第2大的数是4
第四行:[3, 6, 6, 8],第2大的数是6

所有行的第2大数中的最小值是3。

输出:3

五、解题思路

1、深度优先搜索DFS

深度优先搜索(Depth-First Search, DFS)是一种用于遍历或搜索图或树结构的算法。DFS算法从一个起始节点开始,沿着某一路径尽可能深入到一个分支的底部,然后回溯并继续探索其他分支,直到所有节点都被访问过。

DFS的核心思想是尽可能深地搜索树或图的分支,直到遇到已访问的节点或没有未访问的邻接节点为止,然后回溯到上一个节点继续搜索。

2、为什么采用深度优先搜索DFS?

在这个问题中,我们需要从一个矩阵中选择一定数量的元素,这些元素必须满足不在同一行或同一列的限制条件,同时还要找到这些元素中第 K 大的元素的最小值。这种问题的关键在于需要系统地探索所有可能的选择组合,并检查每个组合是否满足特定的条件。

DFS算法通过递归的方式深入搜索,能够遍历所有可能的选择组合。在这个问题中,DFS可以从每个矩阵元素开始,尝试选择下一个元素时递归地检查不同行不同列的约束,直到选择到足够数量的元素为止。这种方法确保不会遗漏任何一个可能的组合。

3、具体步骤:

对于给定的矩阵和选择的数量 K,问题要求从矩阵中选择 K 个数字,这些数字不能位于同一行或同一列,然后找出所有可能组合中第 K 大的数字的最小值。解题的主要步骤如下:

  1. 读取输入数据:
    • 获取矩阵的行数 N、列数 M 和需要选择的数量 K。
    • 读取 N*M 的矩阵数据。
  2. 选择组合:
    • 使用DFS进行深度优先搜索,选择矩阵中的 K 个元素。
    • 在每次选择时,确保选定的数字不在已选数字的行和列中。
  3. 计算组合中第 K 大的数字:
    • 对于每个有效的选择组合,排序并找到该组合中的第 K 大数字。
  4. 记录最小值:
    • 记录所有组合中第 K 大的数字,最终取这些数字中的最小值作为结果。
  5. 输出结果:
    • 输出最小的第 K 大数字。

六、Python算法源码

def main():
    # 读取输入
    N = int(input())
    M = int(input())
    K = int(input())
    matrix = []

    for _ in range(N):
        matrix.append(list(map(int, input().split())))

    # 存储每个组合的第K大的最小值
    min_kth_values = []

    # 从矩阵中选择 K 个数字
    select_numbers(matrix, N, M, K, [], min_kth_values)

    # 找到所有组合中的第 K 大的最小值
    result = min(min_kth_values)
    print(result)

def select_numbers(matrix, N, M, K, current_selection, min_kth_values):
    if len(current_selection) == K:
        # 对于每个选择,找到第 K 大的值
        current_selection.sort()
        min_kth_values.append(current_selection[K - 1])
        return

    for i in range(N):
        for j in range(M):
            if can_be_selected(i, j, current_selection, matrix, N, M):
                current_selection.append(matrix[i][j])
                select_numbers(matrix, N, M, K, current_selection, min_kth_values)
                current_selection.pop()

def can_be_selected(row, col, current_selection, matrix, N, M):
    # 检查行列约束
    for num in current_selection:
        position = find_position(num, matrix, N, M)
        if position[0] == row or position[1] == col:
            return False
    return True

def find_position(num, matrix, N, M):
    for i in range(N):
        for j in range(M):
            if matrix[i][j] == num:
                return (i, j)
    return (-1, -1)  # 不会发生

if __name__ == "__main__":
    main()

七、JavaScript算法源码

function main() {
    const fs = require('fs');
    const input = fs.readFileSync('/dev/stdin', 'utf8').trim().split('\n');
    
    const N = parseInt(input[0]);
    const M = parseInt(input[1]);
    const K = parseInt(input[2]);
    const matrix = [];

    for (let i = 0; i < N; i++) {
        matrix.push(input[3 + i].split(' ').map(Number));
    }

    // 存储每个组合的第K大的最小值
    const minKthValues = [];

    // 从矩阵中选择 K 个数字
    selectNumbers(matrix, N, M, K, [], minKthValues);

    // 找到所有组合中的第 K 大的最小值
    const result = Math.min(...minKthValues);
    console.log(result);
}

function selectNumbers(matrix, N, M, K, currentSelection, minKthValues) {
    if (currentSelection.length === K) {
        // 对于每个选择,找到第 K 大的值
        currentSelection.sort((a, b) => a - b);
        minKthValues.push(currentSelection[K - 1]);
        return;
    }

    for (let i = 0; i < N; i++) {
        for (let j = 0; j < M; j++) {
            if (canBeSelected(i, j, currentSelection, matrix, N, M)) {
                currentSelection.push(matrix[i][j]);
                selectNumbers(matrix, N, M, K, currentSelection, minKthValues);
                currentSelection.pop();
            }
        }
    }
}

function canBeSelected(row, col, currentSelection, matrix, N, M) {
    // 检查行列约束
    for (let num of currentSelection) {
        const position = findPosition(num, matrix, N, M);
        if (position[0] === row || position[1] === col) {
            return false;
        }
    }
    return true;
}

function findPosition(num, matrix, N, M) {
    for (let i = 0; i < N; i++) {
        for (let j = 0; j < M; j++) {
            if (matrix[i][j] === num) {
                return [i, j];
            }
        }
    }
    return [-1, -1]; // 不会发生
}

// 如果在Node.js环境中运行,调用main函数
main();

八、C算法源码

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

#define MAX_N 100

void selectNumbers(int matrix[MAX_N][MAX_N], int N, int M, int K, int* currentSelection, int currentSize, int* minKthValues, int* minKthValuesSize);
int canBeSelected(int row, int col, int* currentSelection, int currentSize, int matrix[MAX_N][MAX_N], int N, int M);
void findPosition(int num, int matrix[MAX_N][MAX_N], int N, int M, int* row, int* col);

int main() {
    int N, M, K;
    int matrix[MAX_N][MAX_N];

    scanf("%d %d %d", &N, &M, &K);

    // 读取矩阵
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            scanf("%d", &matrix[i][j]);
        }
    }

    // 存储每个组合的第K大的最小值
    int minKthValues[MAX_N * MAX_N];
    int minKthValuesSize = 0;
    int currentSelection[MAX_N];

    // 从矩阵中选择 K 个数字
    selectNumbers(matrix, N, M, K, currentSelection, 0, minKthValues, &minKthValuesSize);

    // 找到所有组合中的第 K 大的最小值
    int result = minKthValues[0];
    for (int i = 1; i < minKthValuesSize; i++) {
        if (minKthValues[i] < result) {
            result = minKthValues[i];
        }
    }

    printf("%d\n", result);

    return 0;
}

void selectNumbers(int matrix[MAX_N][MAX_N], int N, int M, int K, int* currentSelection, int currentSize, int* minKthValues, int* minKthValuesSize) {
    if (currentSize == K) {
        // 对于每个选择,找到第 K 大的值
        int sortedSelection[MAX_N];
        for (int i = 0; i < K; i++) {
            sortedSelection[i] = currentSelection[i];
        }
        // 排序选择的元素
        for (int i = 0; i < K - 1; i++) {
            for (int j = 0; j < K - i - 1; j++) {
                if (sortedSelection[j] > sortedSelection[j + 1]) {
                    int temp = sortedSelection[j];
                    sortedSelection[j] = sortedSelection[j + 1];
                    sortedSelection[j + 1] = temp;
                }
            }
        }
        minKthValues[(*minKthValuesSize)++] = sortedSelection[K - 1];
        return;
    }

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (canBeSelected(i, j, currentSelection, currentSize, matrix, N, M)) {
                currentSelection[currentSize] = matrix[i][j];
                selectNumbers(matrix, N, M, K, currentSelection, currentSize + 1, minKthValues, minKthValuesSize);
            }
        }
    }
}

int canBeSelected(int row, int col, int* currentSelection, int currentSize, int matrix[MAX_N][MAX_N], int N, int M) {
    // 检查行列约束
    for (int i = 0; i < currentSize; i++) {
        int r, c;
        findPosition(currentSelection[i], matrix, N, M, &r, &c);
        if (r == row || c == col) {
            return 0;
        }
    }
    return 1;
}

void findPosition(int num, int matrix[MAX_N][MAX_N], int N, int M, int* row, int* col) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (matrix[i][j] == num) {
                *row = i;
                *col = j;
                return;
            }
        }
    }
    *row = -1;
    *col = -1;  // 不会发生
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define MAX_N 100

void selectNumbers(int matrix[MAX_N][MAX_N], int N, int M, int K, vector<int>& currentSelection, vector<int>& minKthValues);
bool canBeSelected(int row, int col, const vector<int>& currentSelection, int matrix[MAX_N][MAX_N], int N, int M);
pair<int, int> findPosition(int num, int matrix[MAX_N][MAX_N], int N, int M);

int main() {
    int N, M, K;
    int matrix[MAX_N][MAX_N];

    cin >> N >> M >> K;

    // 读取矩阵
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> matrix[i][j];
        }
    }

    // 存储每个组合的第K大的最小值
    vector<int> minKthValues;
    vector<int> currentSelection;

    // 从矩阵中选择 K 个数字
    selectNumbers(matrix, N, M, K, currentSelection, minKthValues);

    // 找到所有组合中的第 K 大的最小值
    int result = *min_element(minKthValues.begin(), minKthValues.end());

    cout << result << endl;

    return 0;
}

void selectNumbers(int matrix[MAX_N][MAX_N], int N, int M, int K, vector<int>& currentSelection, vector<int>& minKthValues) {
    if (currentSelection.size() == K) {
        // 对于每个选择,找到第 K 大的值
        vector<int> sortedSelection = currentSelection;
        sort(sortedSelection.begin(), sortedSelection.end());
        minKthValues.push_back(sortedSelection[K - 1]);
        return;
    }

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (canBeSelected(i, j, currentSelection, matrix, N, M)) {
                currentSelection.push_back(matrix[i][j]);
                selectNumbers(matrix, N, M, K, currentSelection, minKthValues);
                currentSelection.pop_back();
            }
        }
    }
}

bool canBeSelected(int row, int col, const vector<int>& currentSelection, int matrix[MAX_N][MAX_N], int N, int M) {
    // 检查行列约束
    for (int num : currentSelection) {
        pair<int, int> position = findPosition(num, matrix, N, M);
        if (position.first == row || position.second == col) {
            return false;
        }
    }
    return true;
}

pair<int, int> findPosition(int num, int matrix[MAX_N][MAX_N], int N, int M) {
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            if (matrix[i][j] == num) {
                return make_pair(i, j);
            }
        }
    }
    return make_pair(-1, -1); // 不会发生
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

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

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

相关文章

华为OD机试 - 跳房子I(Java 2024 E卷 100分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

高效驱动之选 ——KP85211ASGA 半桥栅极驱动器 内置互锁死区

KP85211A是一款 225V 耐压&#xff0c;具有 1A 拉电流和 1.5A 灌电流能力的半桥栅极驱动器&#xff0c;专用于驱动功率MOSFET或IGBT。采用高压器件工艺技术&#xff0c;具有良好的电流输出及出色的抗瞬态干扰能力。可保证开关节点 VS 瞬态 -7V 情况下系统正常工作。可支持开关节…

SpringBoot自定义启动器(自定义Starter)

一、如何理解 SpringBoot 的 starter 机制 Spring Boot 的 Starter 机制是其简化开发流程的关键特性之一。通过提供 预配置的依赖项 和 自动配置 支持&#xff0c;这一机制极大地简化了项目的依赖管理和配置工作&#xff0c;使得开发者可以更快地搭建应用程序框架&#xff0c;…

【系统分析师】计算机组成与体系架构

计算机硬件组成&#xff0c;运算器&#xff0c;控制器 计算机基本硬件系统五大组成部分&#xff1a;运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;I/O设备 运算器的四个重要寄存器&#xff1a; 算术逻辑单元&#xff08;实时对数据的算术和逻辑运算&#xff0c;…

C语言 ——— 学习并使用 #if defined #ifdef #ifndef 条件编译指令

目录 学习 #if defined #ifdef #ifndef 条件编译指令 使用 #if defined 和 #ifdef 条件编译指令 使用 #ifndef 条件编译指令 学习 #if defined #ifdef #ifndef 条件编译指令 #if #ifndef 条件编译指令是用来判断某个符号是否被定义过&#xff0c;被定义过的话就为真&#x…

代码随想录冲冲冲 Day41 动态规划Part9

188. 买卖股票的最佳时机 IV 昨天题目是买卖两次&#xff0c;这里是设定好k次 2次的时候一共包含了5中情况 那么k次就包含了2 k 1种情况 初始化只有1 &#xff0c; 3 &#xff0c;5 也就是买入的状况是有值的&#xff0c;所以初始化时候只需要看这些情况知道2 k 之后只要把…

C++11(2)

目录 6。左值引用和右值引用 下面演示左值和左值引用&#xff1a; 下面演示右值和右值引用&#xff1a; 7。移动构造和移动赋值 VS2022的神级优化 List下的移动构造拷贝和深拷贝(实战) 证明&#xff1a;左值是由编译器决定的 附加&#xff1a;自己实现的List.h 6。左值引…

欺诈文本分类检测(十四):GPTQ量化模型

1. 引言 量化的本质&#xff1a;通过将模型参数从高精度&#xff08;例如32位&#xff09;降低到低精度&#xff08;例如8位&#xff09;&#xff0c;来缩小模型体积。 本文将采用一种训练后量化方法GPTQ&#xff0c;对前文已经训练并合并过的模型文件进行量化&#xff0c;通…

fuxa搭建与使用(web组态)

1. 安装Node.js -> npm安装 参考网址&#xff1a;https://blog.csdn.net/WHF__/article/details/129362462 一、安装运行 C:\WINDOWS\system32>node -v v20.17.0 C:\WINDOWS\system32>npm -v 10.8.2 二、环境配置 在安装路径&#xff08;D:\Program_Files\nodejs&a…

打开VSCod安装“PHP Intelephense”或“PHP Server”PHP扩展

安装PHP扩展&#xff1a; 打开VSCode&#xff0c;进入扩展视图&#xff08;或使用快捷键CtrlShiftX&#xff09;。搜索并安装“PHP Intelephense”或“PHP Server”等PHP相关扩展&#xff0c;这些扩展提供了PHP代码的智能感知、代码导航、调试等功能。 配置PHP路径&#xff1a;…

第2章 方法

本书作者起初以为仅靠研究命令行工具和指标就能提高性能。他认为这样不对。他从头到尾读了一遍手册&#xff0c;看懂了缺页故障、上下文切换和其他各种系统指标的定义&#xff0c;但不知道如何处理它们&#xff1a;如何从发现信号到找到解决方案。 他注意到&#xff0c;每当出…

第 8 章图像内容分类

本章介绍图像分类和图像内容分类算法。首先&#xff0c;我们介绍一些简单而有效的方法和目前一些性能最好的分类器&#xff0c;并运用它们解决两类和多类分类问题&#xff0c;最后展示两个用于手势识别和目标识别的应用实例。 8.1 K邻近分类法&#xff08;KNN&#xff09; 在…

2024最新精选文章!分享5款论文ai生成软件

在2024年&#xff0c;AI论文生成软件的出现极大地提升了学术写作的效率和质量。这些工具不仅能够帮助研究人员快速生成论文草稿&#xff0c;还能进行内容优化、查重和排版等操作。以下是五款值得推荐的AI论文生成软件&#xff0c;其中特别推荐千笔-AIPassPaper。 ### 千笔-AIPa…

shader 案例学习笔记之step函数

step函数 step(edge,x)&#xff1a;当x>edge时返回1&#xff0c;否则返回0 #ifdef GL_ES precision mediump float; #endifuniform vec2 u_resolution;void main(){vec2 st gl_FragCoord.xy/u_resolution.xy;float f step(0.5, st.x);gl_FragColor vec4(f, 0, 0, 1.0); …

JQuery中的$

}); 当jquery.color.js动画插件加载完毕后&#xff0c;单击id为“go”按钮时&#xff0c;class为block的元素就有了颜色动画变化。 $.getJSON() $.getJSON()方法用于加载JSON文件&#xff0c;与$.getScript()方法的用法相同。 我们来看demo2. demo2.html 已有评论&#xff1…

Linux下如何使用CMake实现动态库的封装与调用

一、动态库的封装 1.创建工程 首先创建一个qt工程&#xff08;这里我采用的是ui工程&#xff09; 这里选择Widget工程 名字取一个和动态库相关的即可&#xff0c;我这里取的UIDLL 这里选择CMake 这里我选择命名为Dynamic kits采用Qt 5.14.2 GCC 64bit&#xff0c;之后直接下一…

Qt常用控件——QLabel

文章目录 QLabel核心属性文本格式演示显示图片文本对齐自动换行、边距、缩进设置伙伴 QLabel核心属性 QLabel是显示类控件&#xff0c;可以用来显示文本和图片 属性说明textQLabel中的文本textFormat文本格式Qt::PlainText纯文本Qt::RichText富文本&#xff08;支持html标签&…

html+css网页设计 旅游 雪花旅行社5个页面

htmlcss网页设计 旅游 雪花旅行社5个页面 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&#…

Windows下meson编译libplacebo库

1、安装msys64&#xff0c;添加系统环境变量C:\msys64 2、修改msys64目录下msys2_shell.cmd文件&#xff1a; 去掉“rem set MSYS2_PATH_TYPEinherit” 中rem&#xff0c;以便于shell能继承系统环境变量&#xff0c;然后保存 rem To export full current PATH from environme…

ESP32 TCP通信交换数据Mixly Arduino编程

TCP通信交换数据 在ESP32与ESP32或其它局域网络内主机间传输数据时&#xff0c;TCP是很方便的&#xff0c;特别当我们连接互联网后ESPnow不能用&#xff0c;MQTT又不稳定发送大量的数据&#xff0c;同时蓝牙有其它用途时&#xff0c;那么学会TCP通信协议就变得十分重要。 一、…