最长的顺子 --- 华为od刷题

[斗地主]起源于湖北十堰房县,据说是一位叫吴修全的年轻人根据当地流行的扑克玩法“跑得快”改编的,如今已风靡整个中国,并流行于互联网上。

牌型:单顺,又称顺子,最少5张牌,最多12张牌(3…A)不能有2,也不能有大小王,不计花色。

例如: 3-4-5-6-7-8,7-8-9-10-J-Q,3-4-5-6-7-8-9-10-J-Q-K-A

可用的牌 3<4<5<6<7<8<9<10<J<Q<K<A<2<B(小王)<C(大王),每种牌除大小王外有四种花色

(共有13×4+2张牌)

输入:

  1. 手上有的牌
  2. 已经出过的牌(包括对手出的和自己出的牌)

输出:

  • 对手可能构成的最长的顺子(如果有相同长度的顺子,输出牌面最大的那一个),
  • 如果无法构成顺子,则输出 NO-CHAIN。

输入描述

输入的第一行为当前手中的牌

输入的第二行为已经出过的牌

输出描述

最长的顺子

用例

输入3-3-3-3-4-4-5-5-6-7-8-9-10-J-Q-K-A
4-5-6-7-8-8-8
输出9-10-J-Q-K-A
说明
输入3-3-3-3-8-8-8-8
K-K-K-K
输出NO-CHAIN
说明剩余的牌无法构成顺子

参考题库

华为OD机试备考攻略 以及题库目录分值说明 考点说明

题目描述

C++

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

using namespace std;

// 将牌面映射为数字,方便处理
string mapToNumber(string pai) {
    if (pai == "J") return "11";
    if (pai == "11") return "J";
    if (pai == "Q") return "12";
    if (pai == "12") return "Q";
    if (pai == "K") return "13";
    if (pai == "13") return "K";
    if (pai == "A") return "14";
    if (pai == "14") return "A";
    return pai;
}

string getLongestChain(vector<string> myCards, vector<string> usedCards) {
    // 统计3~A的每张牌的数量,对应数组的索引3~14
    int cardCount[] = {0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0};

    // 从cardCount中去除myCards,剩下的就是对手的牌及数量
    for (string card : myCards) {
        int idx = stoi(mapToNumber(card));
        cardCount[idx]--;
    }

    // 从cardCount中去除usedCards,剩下的就是对手的牌及数量
    for (string card : usedCards) {
        int idx = stoi(mapToNumber(card));
        cardCount[idx]--;
    }

    // res用于保存顺子
    vector<string> res;
    // path用于保存连续的牌
    vector<string> path;

    for (int i = 3; i < sizeof(cardCount) / sizeof(int); i++) {
        // 从牌面3开始遍历,如果牌数量大于0,则加入path
        if (cardCount[i] > 0) {
            path.push_back(to_string(i));
        } else {
            // 如果遇到牌数量为0的,则连续的牌被中断,若此时连续的牌数量大于等于5,则可以形成顺子,我们将顺子加入res中
            if (path.size() >= 5) {
                string str;
                for (string idx : path) {
                    string pai = mapToNumber(idx);
                    str += pai + "-";
                }
                str.pop_back(); // 去掉最后一个"-"
                res.push_back(str);
            }
            // 清空path,为下一次连续的牌腾位置
            path.clear();
        }
    }

    // 如果没有顺子,则返回"NO-CHAIN"
    if (res.size() == 0) return "NO-CHAIN";

    // 如果有顺子,则先按照顺子长度升序,若长度相等,则按照字典序升序
    sort(res.begin(), res.end(), [](string a, string b) {
        return a.length() != b.length() ? a.length() < b.length() : a < b;
    });

    return res[0];
}

int main() {
    vector<string> myCards, usedCards;
    string line;
    getline(cin, line);
    size_t pos = 0;
    string token;
    while ((pos = line.find("-")) != string::npos) {
        token = line.substr(0, pos);
        myCards.push_back(token);
        line.erase(0, pos + 1);
    }
    myCards.push_back(line);

    getline(cin, line);
    pos = 0;
    while ((pos = line.find("-")) != string::npos) {
        token = line.substr(0, pos);
        usedCards.push_back(token);
        line.erase(0, pos + 1);
    }
    usedCards.push_back(line);

    cout << getLongestChain(myCards, usedCards) << endl;

    return 0;
}
#华为机试,emo了##华为od#
全部评论
怎么做题的时候想不到555
点赞 回复 分享
发布于 2023-03-28 12:15 上海

相关推荐

门口唉提是地铁杀:之前b站被一个游戏demo深深的吸引了。看up主页发现是个初创公司,而且还在招人,也是一天60。二面的时候要我做一个登录验证和传输文件两个微服务,做完要我推到github仓库,还要我加上jaeger和一堆运维工具做性能测试并且面试的时候投屏演示。我傻乎乎的做完以后人家跟我说一句现在暂时不招人,1分钱没拿到全是白干
你的秋招第一场笔试是哪家
点赞 评论 收藏
分享
湫湫湫不会java:先投着吧,大概率找不到实习,没实习的时候再加个项目,然后把个人评价和荣誉奖项删了,赶紧成为八股战神吧,没实习没学历,秋招机会估计不多,把握机会。或者说秋招时间去冲实习,春招冲offer,但是压力会比较大
点赞 评论 收藏
分享
评论
3
7
分享

创作者周榜

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