华为上机真题斗地主之顺子

Posted Linux猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华为上机真题斗地主之顺子相关的知识,希望对你有一定的参考价值。

🎈 作者:Linux猿

🎈 简介:CSDN博客专家🏆,华为云享专家🏆,Linux、C/C++、云计算、物联网、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

🎈 关注专栏: 数据结构和算法成神路【精讲】优质好文持续更新中……🚀🚀🚀

🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬


 

目录

一、题目描述

1.1 输入描述

1.2 输出描述

1.3 测试样例

1.3.1 示例 1

1.3.2 示例 2

1.3.3 示例 3

二、解题思路

三、代码实现

四、时间复杂度


一、题目描述

在斗地主扑克牌游戏中,扑克牌由小到大的顺序为:3、4、5、6、7、8、9、10、J、Q、K、A、2。玩家可以出的扑克牌阵型有:单张、对子、顺子、飞机、炸弹等。

其中顺子的出牌规则为:由至少 5 张由小到大连续递增的扑克牌组成,且不包括 2。

例如:3,4,5,6,7 、3、4、5、6、7、8、9、10、J、Q、K、A 都是有效的顺子;

而 J、Q、K、A、2、2、3、4、5、6、3、4、5、6、3、4、5、6、8 等都不是顺子。

给定一个包含 13 张牌的数组,如果有满足出牌规则的顺子,请输出顺子。

如果存在多个顺子,请每行输出一个顺子,且需要按顺子第一张牌的大小(从小到大)依次输出。

如果没有满足出牌规则的顺子,请输出 NO。

1.1 输入描述

13 张任意顺序的扑克牌,每张扑克牌数字用空格隔开,每张扑克牌的数字都是合法的,并且不包括大小王。

2 9 J 2 3 4 K A 7 9 A 5 6

注意:不需要考虑输入为异常字符的情况

1.2 输出描述

组成的顺子,每张扑克牌数字用空格隔开

3 4 5 6 7

1.3 测试样例

1.3.1 示例 1

输入

2 9 J 2 3 4 K A 7 9 A 5 6

输出

3 4 5 6 7

说明:13 张牌中,可以组成的顺子只有 1 组:3 4 5 6 7

1.3.2 示例 2

输入

2 9 J 10 3 4 K A 7 Q A 5 6

输出

3 4 5 6 7
9 10 J Q K A

说明:13 张牌中,可以组 2 组顺子,从小到大分别为:3 4 5 6 7 和 9 10 J Q K A

1.3.3 示例 3

输入

2 9 9 9 3 4 K A 10 Q A 5 6

输出

NO

说明:13张牌中,无法组成顺子
 

二、解题思路

本题属于模拟题,首先,统计每张牌有多少张,因为牌有 J、K、Q、A 等字符,可以将牌重新排序,指定每张牌的具体数值,例如:3 对应 0,4 对应 1,以此类推,A 对应 11,因为 2 用不到,可以让 2 对应 13。统计完每张牌的具体数量后,从 0 开始依次判断是否是顺子,是则输出,并将对应牌的数值减一。

三、代码实现

代码实现如下所示。

#include <iostream>
#include <map>
#include <string>
#include <sstream>
#include <cstring>
using namespace std;

map<string, int>mp;
void init()

    mp["2"] = 13;
    mp["3"] = 0;
    mp["4"] = 1;
    mp["5"] = 2;
    mp["6"] = 3;
    mp["7"] = 4;
    mp["8"] = 5;
    mp["9"] = 6;
    mp["10"] = 7;
    mp["J"] = 8;
    mp["Q"] = 9;
    mp["K"] = 10;
    mp["A"] = 11;


void print(int x, int y)

    for (int i = x; i < y; ++i) 
        if (i != x) 
            cout<<" ";
        
        if (i >= 0 && i <= 7) 
            cout<<i + 3;
         else if (i == 8) 
            cout<<'J';
         else if (i == 9) 
            cout<<'Q';
         else if (i == 10) 
            cout<<'K';
         else if (i == 11) 
            cout<<'A';
        
    
    cout<<endl;


int main()

    init();
    string str;
    while (getline(cin, str)) 
        int num[15];
        memset(num, 0, sizeof(num));
        stringstream stream(str);
        while (getline(stream, str, ' ')) 
            num[mp[str]]++;
        

        bool ans = false;
        for (int i = 0; i < 12; ++i) 
            int j = i;
            while (j < 12) 
                if (num[j] == 0) 
                    break;
                
                ++j;
            
            if (j > i + 4) 
                ans = true;
                for (int k = i; k < j; ++k) 
                    num[k]--;
                
                print(i, j);
            
        
        if (!ans) 
            cout<<"NO"<<endl;
        
    
    return 0;

四、时间复杂度

时间复杂度:O(n)

在上述代码中,主要时间消耗在遍历字符串上,假设字符串长度为 n,即时间复杂度为 O(n)。


🎈 感觉有帮助记得「一键三连支持下哦!有问题可在评论区留言💬,感谢大家的一路支持!🤞猿哥将持续输出「优质文章回馈大家!🤞🌹🌹🌹🌹🌹🌹🤞


以上是关于华为上机真题斗地主之顺子的主要内容,如果未能解决你的问题,请参考以下文章

华为机试真题 C++ 实现斗地主之顺子

华为OD机试真题 Python 实现斗地主之顺子

华为OD机试真题 Python 实现最长的顺子

2022&2023华为OD机试 - 斗地主 2(Python)

剑指offer(三十)之扑克牌顺子

剑指offer四十六之扑克牌顺子(序列是否连续)