最长连续手牌 - 华为OD统一考试

news2024/11/27 19:56:13

OD统一考试(C卷)

分值: 200分

题解: Java / Python / C++

alt

题目描述

有这么一款单人卡牌游戏,牌面由颜色和数字组成,颜色为红、黄、蓝、绿中的一种,数字为 0−9 中的一个。游戏开始时玩家从手牌中选取一张卡牌打出,接下来如果玩家手中有和他上一次打出的手牌颜色或者数字相同的手牌,他可以继续将该手牌打出,直至手牌打光或者没有符合条件可以继续打出的手牌。

现给定一副手牌,请找到最优的出牌策略,使打出的手牌最多。

输入描述

第一行是每张手牌的数字,数字由空格分隔

第二行为对应的每张手牌的颜色,用 rybg 这 4 个字母分别代表 4 种颜色,字母也由空格分隔。

手牌数量不超过10。

输出描述

输出一个数字,即最多能打出的手牌的数量。

示例1

输入:
1 4 3 4 5
r y b b r

输出:
3

说明:
如果打(1,r)-> (5,r),那么能打两张。如果打(4,y) -> (4,b) -> (3,b),那么能打三张。

示例2

输入:
1 2 3 4
r y b l

输出:
1

说明:
没有能够连续出牌的组合,只能在开始时打出一张手牌,故输出 1 。

题解

题目类型: 深度优先搜索(DFS)

解题思路:

  1. 通过深度优先搜索遍历所有可能的出牌组合。
  2. 维护一个全局变量 maxCnt,记录最多能打出的手牌数。
  3. 递归函数 dfs 中,遍历未使用过的手牌,判断是否能打出。如果可以,标记为已使用,继续递归下一层。
  4. 在递归的过程中更新 maxCnt
  5. 最终返回 maxCnt

时间复杂度: 搜索的时间复杂度取决于搜索空间的大小,最坏情况下为 O(2^n),其中 n 为手牌数量。每张牌有两种状态:打出或不打出。

空间复杂度: 递归调用的深度为手牌数量,因此空间复杂度为 O(n)。

Java

import java.util.Arrays;
import java.util.Objects;
import java.util.Scanner;

/**
 * @author code5bug
 */
public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        // 读取卡牌数字列表
        int[] nums = Arrays.stream(in.nextLine().split(" "))
                .mapToInt(Integer::parseInt).toArray();

        // 读取卡牌颜色列表
        String[] colors = in.nextLine().split(" ");

        Solution solution = new Solution();
        // 调用 solve 方法求解并输出结果
        int result = solution.solve(nums, colors);
        System.out.println(result);
    }

}


class Solution {

    private int maxCnt;

    public int solve(int[] nums, String[] colors) {
        this.maxCnt = 0;
        dfs(-1, 0, nums, colors, new boolean[nums.length]);
        return this.maxCnt;
    }

    private void dfs(int prev, int cnt, int[] nums, String[] colors, boolean[] vis) {
        // 更新最多可以打出的手牌数
        this.maxCnt = Math.max(cnt, this.maxCnt);

        for (int cur = 0; cur < nums.length; cur++) {
            if (vis[cur]) continue;

            // 之前未打出牌 或 和前面牌数相同 或 和前面牌颜色相同
            if (prev == -1 || nums[prev] == nums[cur] || Objects.equals(colors[prev], colors[cur])) {
                vis[cur] = true;
                dfs(cur, cnt + 1, nums, colors, vis);  // 打出当前的牌
                vis[cur] = false;
            }
        }
    }
}

Python

from typing import List


def solve(nums: List[int], colors: list[str]) -> int:
    # 卡牌数量, 最多可以打出的手牌数
    n, max_cnt = len(nums), 0
    vis = [False] * n

    def dfs(prev, cnt):
        """
        param: prev 前一张打出的牌
        param: cnt 已经打出的手牌数
        """
        nonlocal max_cnt, n, vis
        max_cnt = max(cnt, max_cnt)  # 更新最多可以打出的手牌数

        for cur in range(n):
            if vis[cur]:
                continue
            # 之前未打出牌 或 和前面牌数相同 或 和前面牌颜色相同
            if prev == -1 or nums[prev] == nums[cur] or colors[prev] == colors[cur]:
                vis[cur] = True
                dfs(cur, cnt + 1)  # 打出 cur 当前的牌
                vis[cur] = False

    dfs(-1, 0)

    return max_cnt


if __name__ == "__main__":
    nums = list(map(int, input().split()))
    colors = list(map(str, input().split()))
    print(solve(nums, colors))

C++

#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

template <typename T>
vector<T> readList() {
    string input;
    getline(cin, input);
    stringstream stream(input);
    vector<T> result;
    T value;
    while (stream >> value) {
        result.push_back(value);
    }
    return result;
}

int maxCnt;

void dfs(int prev, int cnt, vector<int>& nums, vector<string>& colors, vector<bool>& vis) {
    // 更新最多可以打出的手牌数
    maxCnt = max(cnt, maxCnt);

    for (size_t cur = 0; cur < nums.size(); cur++) {
        if (vis[cur]) continue;

        // 之前未打出牌 或 和前面牌数相同 或 和前面牌颜色相同
        if (prev == -1 || nums[prev] == nums[cur] || colors[prev] == colors[cur]) {
            vis[cur] = true;
            dfs(cur, cnt + 1, nums, colors, vis);  // 打出当前的牌
            vis[cur] = false;
        }
    }
}

int main() {
    // 读取卡牌数字列表
    vector<int> nums = readList<int>();

    // 读取卡牌颜色列表
    vector<string> colors = readList<string>();

    maxCnt = 0;

    // 调用 dfs 方法求解并输出结果
    vector<bool> vis(nums.size(), false);
    dfs(-1, 0, nums, colors, vis);
    cout << maxCnt << endl;

    return 0;
}

‍❤️‍华为OD机试面试交流群每日真题分享): 加V时备注“华为od加群”

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

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

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

相关文章

力扣hot3--并查集+哈希

第一想法是排个序然后遍历一遍&#xff0c;but时间复杂度就超啦 并查集居然与哈希结合了&#xff08;&#xff09; 已经好久没用过并查集了&#xff0c;&#xff0c;&#xff0c;我们用哈希表f_node中来记录原结点的父节点&#xff0c;其中key是原结点&#xff0c;value是父节点…

OpenHarmony—UIAbility组件生命周期

概述 当用户打开、切换和返回到对应应用时&#xff0c;应用中的UIAbility实例会在其生命周期的不同状态之间转换。UIAbility类提供了一系列回调&#xff0c;通过这些回调可以知道当前UIAbility实例的某个状态发生改变&#xff0c;会经过UIAbility实例的创建和销毁&#xff0c;…

代码随想录算法训练营第二十七天|贪心算法理论基础,455.分发饼干,376. 摆动序列,53. 最大子序和

系列文章目录 代码随想录算法训练营第一天|数组理论基础&#xff0c;704. 二分查找&#xff0c;27. 移除元素 代码随想录算法训练营第二天|977.有序数组的平方 &#xff0c;209.长度最小的子数组 &#xff0c;59.螺旋矩阵II 代码随想录算法训练营第三天|链表理论基础&#xff…

抖音私信自动回复工具使用教程!

该工具基于网页版抖音&#xff0c;可以用于抖音个人号等任何权限的账号&#xff01; 获取软件 联系我的v 信&#xff1a;llike620 基本使用 了解GPT的&#xff0c;可以配置FastGPT这种训练知识库的AI进行回复 不了解的&#xff0c;可以配置关键词回复 点击抖音私信按钮&a…

Linux设置jar包开机自启动

步骤 1、新建jar包自启文件 sudo vi /etc/init.d/jarSysInit.sh 按i键进入编辑模式输入以下内容&#xff1a; export JAVA_HOME/home/jdk/jdk-11.0.22 export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/jre/lib/rt.jar export PATH$PATH:$JAVA_…

H5大气的互联网建站服务公司静态HTML网站模板源码

H5大气的互联网建站服务公司静态HTML网站模板源码 源码介绍&#xff1a;一款大气的互联网建站服务公司/工作室静态HTML网站模板&#xff0c;带有多个单页&#xff0c;可自行二开作为工作室或公司官网。 下载地址&#xff1a; https://www.changyouzuhao.cn/13456.html

人力资源智能化管理项目(day08:云存储)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/humanResourceIntelligentManagementProject 存储桶列表 &#xff1a;登录 - 腾讯云 API密钥管理&#xff1a;登录 - 腾讯云 上传图片-创建腾讯云存储桶 存储桶名称&#xff1a;intelligentmanagement-1306913843 地…

【Qt】环境安装与初识

目录 一、Qt背景介绍 二、搭建Qt开发环境 三、新建工程 四、Qt中的命名规范 五、Qt Creator中的快捷键 六、QWidget基础项目文件详解 6.1 .pro文件解析 6.2 widget.h文件解析 6.3 widget.cpp文件解析 6.4 widget.ui文件解析 6.5 main.cpp文件解析 七、对象树 八、…

Rust中不可变变量与const有何区别?

Rust作者认为变量默认应该是immutable&#xff0c;即声明后不能被改变的变量。这一点是让跨语言学习者觉得很别扭&#xff0c;不过这一点小的改变带来了诸多好处&#xff0c;本节我们来学习Rust的变量。 什么是变量&#xff1f; 如果你初次学习编程语言&#xff0c;变量会是一…

AlmaLinux更换鼠标样式为Windows样式

文章目录 前言先看看条件与依赖第一步&#xff1a;测试最终效果第二步&#xff1a;使用CursorXP修改鼠标样式CurosrXP安装CursorXP使用 第三步&#xff1a;Linux端环境搭建与命令执行UbuntuFedora其他系统均失败 第四步&#xff1a;应用主题 前言 只不过是突发奇想&#xff0c…

相机图像质量研究(17)常见问题总结:CMOS期间对成像的影响--靶面尺寸

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

如何使用python在三天内制作出一个赛车游戏

制作一个赛车游戏是一个复杂的过程&#xff0c;涉及多个方面&#xff0c;如游戏设计、图形渲染、物理引擎、用户输入处理等。在三天内完成这个任务可能非常具有挑战性&#xff0c;特别是如果你是初学者。但如果你有基本的Python编程知识和一些游戏开发经验&#xff0c;以下是一…

假期day12

任务调度算法&#xff1a; 1.抢占式调度&#xff1a;高优先级的任务优先执行&#xff0c;并且可以打断低优先级的任务执行。 2.时间片轮转&#xff1a;相同优先级的任务&#xff0c;拥有相同的时间片&#xff08;1ms&#xff09;&#xff0c;当时间片被耗尽&#xff0c;就退出…

Github项目推荐-Tiny-Rdm

项目地址 GitHub - tiny-craft/tiny-rdm: A Modern Redis GUI Client 项目简述 一个开源的Redis管理工具&#xff0c;有漂亮的界面和丰富的功能。使用的编程语言如下 项目截图

C语言第二十五弹---字符函数和字符串函数(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 目录 1、字符分类函数 2、字符转换函数 3、strlen的使用和模拟实现 4、strcpy 的模拟实现 5、strcat 的模拟实现 6、strcmp 的模拟实现 7、strncpy 函数的使用 总结…

【Pygame手册02/20】pygame模块display控制窗口和屏幕

目录 一、说明二、pygame.display接口函数2.1 函数表格2.2 pygame.display的功能 三、详细的函数调用3.1 pygame.display.init()3.2 pygame.display.quit()3.3 pygame.display.get_init()3.4 pygame.display.set_mode()3.5 pygame.display.get_surface()3.6 pygame.display.fl…

qml之Control类型布局讲解,padding属性和Inset属性细讲

1、Control布局图 2、如何理解&#xff1f; *padding和*Inset参数如何理解呢&#xff1f; //main.qml import QtQuick 2.0 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 1.4 import QtQml 2.12ApplicationWindow {id: windowvisible: …

ChatGPT绘图指南:DALL.E3玩法大全(二)

在前一篇文章中&#xff0c;我们介绍了什么是 DALL.E3 模型&#xff0c; DALL.E3 有什么优势&#xff0c;使用DALL.E3 的两种方法&#xff0c;以及DALL.E3 绘图的基本规则&#xff0c; 感兴趣的朋友请前往查看: ChatGPT绘图指南&#xff1a;DALL.E3玩法大全(一). 接下来&#…

插值(一)——多项式插值(C++)

插值 插值的作用是可以将原本比较难计算的函数转换为误差在一定范围内的多项式&#xff0c;比如在单片机中直接计算 x 、 log ⁡ 2 x \sqrt{x}、\log_2x x ​、log2​x之类的函数是比较麻烦的&#xff0c;但是使用插值的方法就可以将其转换为误差可控的只有乘法和加减法的多项…

EF Core 模型优先——根据类对象创建数据表

需要的nuget包&#xff1a; Microsoft.EntityframeworkCore.SqlServer &#xff08;根据自己的数据库类型选择对应的nuget包&#xff09; Microsoft.EntityframeworkCore.Tools Microsoft.VisualStudio.Web.CodeGeneration.Design 说明&#xff1a; &#xff08;1&#xf…