华为OD机试 - 数字排列 - 深度优先搜索dfs算法(Java 2024 C卷 100分)

news/2024/7/20 23:03:37 标签: 算法, 华为od, 深度优先

在这里插入图片描述

目录

    • 专栏导读
    • 一、题目描述
    • 二、输入描述
    • 三、输出描述
      • 1、输入
      • 2、输出
      • 3、说明
    • 四、解题思路
    • 五、Java算法源码
    • 六、效果展示
      • 1、输入
      • 2、输出
      • 3、说明

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

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷+C卷)》。

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

小明负责公司年会,想出一个趣味游戏:

屏幕给出1~9任意4个不重复的数字,大家以最快的时间给出这几个数字可拼成的数字从小到大排列位于第N位置的数字,其中N为给出数字中最大的数(如果不到这么多数字,则给出最后一个即可)。

注意:

  • 2可以当做5来使用,5也可以当做2来使用进行数字拼接,且屏幕不能同时给出2和5;
  • 6可以当做9来使用,9也可以当做6来使用进行数字拼接,且屏幕不能同时给出6和9;

如给出:1,4,8,7,则可以拼接的数字为:

1,4,7,8,14,17,18,41,47,48,71,74,78,81,84,87,147,148,178,187…

那么第N个数字,即第8个数字为41,输出41。

二、输入描述

输入以逗号分隔的4个1~9的数字组成的字符串。

三、输出描述

输出这几个数字可拼成的数字从小到大排列位于第N位置的数字,其中N为给出数字中最大的数。

如果输入的数字不在规定的范围内或有重复,则输出-1

1、输入

1,4,8,7

2、输出

41

3、说明

可以拼接的数字为:

1,4,7,8,14,17,18,41,47,48,71,74,78,81,84,87,147,148,178,187…

那么第N个数字,即第8个数字为41,输出41。

四、解题思路

  1. 输入4个1~9的数字,升序排序;
  2. 校验输入合法性;
    • 如果不足4个数字,则输出-1;
    • 输入必须是1~9的数字;
    • 不能同时包含2和5;
    • 不能同时包含6和9;
  3. 取最大的数N;
  4. 通过深度优先搜索dfs算法,拼接所有数字,参数依次为(输入的4位数数组、数字是否使用过、拼接的数字)
  5. 获取组成的数字从小到大排序后第N个数字。

五、Java算法源码

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Test03 {
    static int N = 0;
    static StringBuilder builder = new StringBuilder();
    static int ret = -1;
    static Map<Integer,Integer> map = new HashMap<>();
    static {
        map.put(2,5);
        map.put(5,2);
        map.put(6,9);
        map.put(9,6);
    }

    /**
     * 2和5可以互换,且不能同时出现
     * 6和9可以互换,且不能同时出现
     */
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 5,7,1,6
        int[] arr = Arrays.stream(sc.nextLine().split(",")).mapToInt(Integer::parseInt).toArray();

        Arrays.sort(arr);// 升序排序 1 5 6 7

        // 校验输入合法性
        if (!checkNum(arr)) {
            System.out.println(-1);
            return;
        }

        N = arr[3];// 取最大的数

        boolean[] usedArr = new boolean[4];

        dfs(arr, usedArr, "");

        // 获取组成的数字从小到大排序后第N个数字
        System.out.println(getNumInN(builder));
    }

    static String start = "";

    /**
     * @param arr     输入的4位数数组 1 5 6 7
     * @param usedArr 数字是否使用过
     * @param tempNum 拼接的数字
     */
    private static void dfs(int[] arr, boolean[] usedArr, String tempNum) {
        builder.append(tempNum).append(",");

        for (int i = 0; i < arr.length; i++) {
            // 如果当前数用过了,则跳过
            if (usedArr[i]) {
                continue;
            }
            usedArr[i] = true;
            dfs(arr, usedArr, tempNum + arr[i]);

            if(map.containsKey(arr[i])){
                dfs(arr, usedArr, tempNum + map.get(arr[i]));
            }

            usedArr[i] = false;
        }
    }

    private static boolean checkNum(int[] arr) {
        // 如果不足4个数字,则输出-1
        if (arr.length != 4) {
            return false;
        }

        int sum2 = 0;
        int sum6 = 0;
        for (int i = 0; i < arr.length; i++) {
            int n = arr[i];
            // 输入必须是1~9的数字
            if (n < 1 || n > 9) {
                return false;
            }
            // 不能同时包含2和5
            if (n == 2 || n == 5) {
                sum2++;
            }
            // 不能同时包含6和9
            if (n == 6 || n == 9) {
                sum6++;
            }
        }

        if (sum2 > 1 || sum6 > 1) {
            return false;
        }

        return true;
    }

    // 获取组成的数字从小到大排序后第N个数字
    private static int getNumInN(StringBuilder builder) {
        builder.deleteCharAt(0);
        builder.deleteCharAt(builder.length() - 1);
        int[] arr = Arrays.stream(builder.toString().split(",")).mapToInt(Integer::parseInt).toArray();
        Arrays.sort(arr);//升序排序
        return arr[N - 1];
    }
}

六、效果展示

1、输入

1,4,8,7

2、输出

41

3、说明

获取组成的数字从小到大排序后第8个数字:

1,4,7,8,14,17,18,41,47,48,71,74,78,81,84,87,147,148,174,178,184,187…

即为41。

在这里插入图片描述


🏆下一篇:华为OD机试 - 最长的顺子 - 感谢@禁止你发言提供的更简便算法(Java 2023 B卷 200分)

🏆本文收录于,华为OD机试(JAVA)真题(A卷+B卷+C卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述


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

相关文章

改造muduo,不依赖boost,用C++11重构

组件的实现 1. 序 1.1. 总述 muduo库是基于多Reactor-多线程模型实现的TCP网络编程库&#xff0c;性能良好。如libev作者&#xff1a;“One loop per thread is usually a good model”&#xff0c;muduo库的作者陈硕在其《Linux多线程服务端编程》中也力荐这种“One loop pe…

如何压缩excel中图片大小?快速改变图片大小的方法

在日常工作和学习中&#xff0c;我们经常使用Excel表格来处理数据和信息&#xff0c;有时候&#xff0c;我们可能需要在Excel中插入图片以便更好地展示和说明数据。然而&#xff0c;随着图片的增加&#xff0c;Excel文件的大小也会相应增加&#xff0c;这可能会导致文件过大、加…

Java多线程导入Excel示例

在导入Excel的时候&#xff0c;如果文件比较大&#xff0c;行数很多&#xff0c;一行行读往往速度比较慢&#xff0c;为了加快导入速度&#xff0c;我们可以采用多线程的方式 话不多说直接上代码 首先是Controller import com.sakura.base.service.ExcelService; import com.s…

ArcGIS学习(十)城市用地对比分析

ArcGIS学习(十)城市用地对比分析 1.城市用地变更分析 本任务给大家带来的内容是城市用地对比分析,包括两个关卡:城市用地变更分析 用地规划方案实施评价 城市用地变更分析和用地规划方案实施评价是我们进行用地分析时常见的两种场景。其中:城市用地变更分析主要是对不同…

(七步走写摘要): UserInformation bottleneck fusion for deep multi-view clustering

原摘要: Multi-view clustering aims to employ semantic information from multiple perspectives to accomplish the clustering task. However, a crucial concern in this domain is the selection of distinctive features. Most existing methods map data into a single…

【国产MCU】-CH32V307-实时时钟(RTC)

实时时钟(RTC) 文章目录 实时时钟(RTC)1、实时时钟(RTC)介绍2、RTC驱动API介绍3、RTC使用实例RTC 实时时钟是一组32 位可编程计数器,时基支持20 位预分频,用于较长时间段的测量。时钟基准来源高速的外部时钟128分频(HSE/128)、外部晶体低频振荡器(LSE)或内部低功耗RC…

linux小记(1)

基本概念&#xff1a;不依靠扩展名来区分文件类型 好处&#xff1a;除了文本文件其他所有windows文件都无法在Linux下运行&#xff0c;包括病毒木马。 坏处&#xff1a;所有的软件都需要对linux单独开发 习惯用后缀来区分文件&#xff0c;方便管理。 -压缩包&#xff1a;*.…

tomcat nginx 动静分离

实验目的:当访问静态资源的时候&#xff0c;nginx自己处理 当访问动态资源的时候&#xff0c;转给tomcat处理 第一步 关闭防火墙 关闭防护 代理服务器操作&#xff1a; 用yum安装nginx tomcat &#xff08;centos 3&#xff09;下载 跟tomcat&#xff08;centos 4&#xff0…