最长连续手牌

华为OD统一考试

题目描述

有这么一款单人卡牌游戏,牌面由颜色和数字组成,颜色为红、黄、蓝、绿中的一种,数字为 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)。

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##C++#
C++笔试真题题解 文章被收录于专栏

笔试真题题解

全部评论

相关推荐

03-06 12:44
已编辑
门头沟学院 Java
是个千人厂,没听过名字。1.&nbsp;做一个自我介绍。2.&nbsp;你这个项目和技术栈从哪里学的?有报辅导班嘛[答&nbsp;都是是自己网上学的,学校教的东西没用]3.&nbsp;我看了你放在github上的项目,前端也是你写的嘛[答&nbsp;AI写的,90%精力用于后端开发,前端单纯用于作为后端逻辑的可视化技术验证(骗你的其实后端也是AI写的)]4.&nbsp;好,你觉得这些技术栈研究得最深刻的是哪个[答&nbsp;八股压根没背到后面,昨晚背了MySQL就说MySQL]5.&nbsp;那讲一下MySQL的索引[答&nbsp;从B+树选型一路吟唱到联合索引,索引失效]6.&nbsp;联合索引ABC问题,AB走索引嘛,BC走索引嘛?BAC走索引嘛?A&nbsp;or&nbsp;B&nbsp;走索引嘛[走,不走,走,不走。面试官点头说可以]7.&nbsp;讲一下项目里Redission分布式锁实现8.&nbsp;Watchdog机制具体是怎么工作9.&nbsp;消息队列有考虑过Kafka嘛,怎么选型的10.&nbsp;你这个项目消息队列可能出现什么问题,怎么解决这个问题?[瞎扯没用的,被面试官引导答了视频处理可能产生消息堆积问题,然后开始吟唱]11.&nbsp;文件分片自己写的还是用的什么框架?上传进度的Redis数据结构?上传的视频有多大?小分片大小?12.&nbsp;项目里Redis会话记忆是啥意思?[面试官说不行,没人把这个全放Redis里[生气R]]13.&nbsp;那这和直接查数据库有什么区别[扯了Token成本和解决幻觉问题之类的,给面试官听笑了,我最后也没绷住]14.&nbsp;你平时是怎么使用AI&nbsp;coding的15.&nbsp;算法,给了我一个leedcode链接,一看做过了。然后换了一道三数之和,也做过了。然后面试官说算了,让我讲讲思路吧反问:1.有什么需要提高的地方2.介绍一下部门业务有哪些这个面试官真的感官非常非常好,问问题还疯狂引导,感觉不会也会了。找实习&nbsp;&nbsp;牛客AI配图神器#
查看15道真题和解析
点赞 评论 收藏
分享
评论
4
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务