机试题——连续出牌数量

news/2025/2/1 6:31:57 标签: 算法, c++

题目描述

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

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

输入描述

输入为两行:

  • 第一行是手牌的数字,每张卡牌的数字由空格分隔。
  • 第二行是手牌对应的颜色,颜色由 r(红)、y(黄)、b(蓝)、g(绿)四个字母组成,字母之间用空格分隔。

手牌的数量不超过10。

输出描述

输出一个整数,表示最多能够打出的手牌的数量。

用例输入

输入:

1 4 3 4 5 
r y b b r
3

说明:可以按照(4, y)-> (4, b) -> (3, b) 的顺序打出3张牌。

输入:

1 2 3 4 
r y b l
1

说明:没有任何连续的出牌组合,最多只能打出1张牌。

解题思路

  1. 问题理解

    • 需要根据手牌的颜色或数字,寻找可以连续打出的手牌数量。每次出牌后,下一张牌必须与上一次出牌的颜色或数字匹配才能继续打出。
  2. 回溯与递归

    • 使用回溯算法(DFS)来递归选择每一张手牌,尝试找到最多能够连续打出的手牌数量。
    • 对于每一张当前牌,如果与上一次打出的牌的颜色或数字相匹配,则可以继续打出。
    • 我们用递归来尝试从每张卡牌出发,逐步计算最多能打出的手牌数量。
  3. 避免重复

    • 通过 used 数组标记哪些卡牌已经被打过,避免在同一次递归中重复打出同一张卡牌。
  4. 递归返回的值

    • 递归的返回值表示当前从某一张卡牌出发,最多能够打出的手牌数量。每次递归时,我们尝试从当前卡牌出发继续出牌,直到没有符合条件的卡牌可以打出为止。
  5. 优化

    • 每次递归时不直接加上当前手牌,而是通过递归计算剩余手牌的数量。
    • 每次出牌后,恢复 used 数组,确保其他路径的递归不受影响。

代码

#include <iostream>
#include <vector>
#include <map>
#include <climits>
#include <algorithm>
#include <string>
#include <sstream>
using namespace std;
vector<int> numbers;
vector<char> colors;
vector<bool> used(100, false);
// 上一张牌的数字,上一张牌的颜色
int dfs(int last_num, char last_col) {
    int max_count = 0;
    for (int i = 0; i < numbers.size(); ++i) {
        if (!used[i] && (numbers[i] == last_num || colors[i] == last_col)) {
            used[i] = true;
            max_count = max(max_count, 1 + dfs(numbers[i], colors[i]));
            used[i] = false;
        }
    }
    return max_count;
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    string num_input, color_input;

    getline(cin, num_input); // 读取数字行
    getline(cin, color_input); // 读取颜色行

    // 解析输入
    stringstream ss_num(num_input), ss_color(color_input);
    int num;
    char color;
    while (ss_num >> num) {
        numbers.push_back(num);
    }
    while (ss_color >> color) {
        colors.push_back(color);
    }

    int n = numbers.size();
    int res = 1;
    for (int i = 0; i < n; ++i) {
        // 从第i张卡牌开始
        used[i] = true;
        res = max(res, 1 + dfs(numbers[i], colors[i]));
        used[i] = false;
    }
    cout << res << "\n";
}

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

相关文章

Python之如何在Visual Studio Code 中写的python程序打包成可以在Windows系统下运行的.exe程序

要将你在 Visual Studio Code 中编写的 Python 程序打包成可以在 Windows 系统下运行的 .exe 文件&#xff0c;可以使用 PyInstaller 工具。以下是详细的操作步骤&#xff1a; 1. 安装 PyInstaller 首先&#xff0c;你需要安装 PyInstaller。打开终端&#xff08;可以在 VS C…

LeetCode 349: 两个数组的交集

LeetCode 349: 两个数组的交集 - C语言 问题描述 给定两个数组 ransomNote 和 magazine&#xff0c;你需要判断 ransomNote 是否可以由 magazine 里的字符构成。每个字符可以使用一次。 解题思路 通过统计 magazine 中每个字符的频次&#xff0c;并与 ransomNote 中字符的需…

第24节课:前端性能优化—提升网页加载速度的关键策略

目录 前端性能优化的重要性资源压缩与合并资源压缩HTML压缩CSS压缩JavaScript压缩 资源合并CSS文件合并JavaScript文件合并 懒加载与预加载懒加载图片懒加载 预加载预加载关键资源 实践&#xff1a;综合应用性能优化技术示例&#xff1a;优化一个电商网站 结语 在当今这个信息爆…

多模态论文笔记——NaViT

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细解读多模态论文NaViT&#xff08;Native Resolution ViT&#xff09;&#xff0c;将来自不同图像的多个patches打包成一个单一序列——称为Patch n’ Pack—…

nodejs:express + js-mdict 网页查询英汉词典

向 DeepSeek R1 提问&#xff1a; 我想写一个Web 前端网页&#xff0c;后台用 nodejs js-mdict, 实现在线查询英语单词 1. 项目结构 首先&#xff0c;创建一个项目目录&#xff0c;结构如下&#xff1a; mydict-app/ ├── public/ │ ├── index.html │ ├── st…

数据分析系列--⑥RapidMiner构建决策树(泰坦尼克号案例含数据)

一、资源下载 二、数据处理 1.导入数据 2.数据预处理 三、构建模型 1.构建决策树 2.划分训练集和测试集 3.应用模型 4.结果分析 一、资源下载 点击下载数据集 二、数据处理 1.导入数据 2.数据预处理 三、构建模型 1.构建决策树 虽然决策树已经构建,但对于大多数初学者或…

TensorFlow 手动构建一个神经网络

TensorFlow 和 Keras 来构建和训练一个简单的神经网络模型。我们来逐行解析它的功能 import tensorflow as tf import numpy as np tensorflow&#xff1a;导入 TensorFlow 库&#xff0c;TensorFlow 是一个开源的机器学习框架。numpy&#xff1a;导入 NumPy 库&#xff0c;它…

27.Word:财务软件应用的书稿【10】

目录 NO1.2 NO3 NO5.6​ NO7.8​ NO9​ 存在页码链接关系&#xff0c;只是页码格式不同 NO1.2 另存为/F12&#xff1a;考生文件夹布局→页面设置对话框→页边距&#xff1a;上下内外/装订线→纸张大小→布局&#xff1a;页眉页脚 NO3 样式的应用&#xff1a;超快速❗ 开…