69. 斗地主之顺子

287 阅读2分钟

题目描述

在斗地主只扑克牌游戏中,扑克牌由小到大的顺序为: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}都是有效的顺子;而{,Q,K,A,2}、(2,3,4,5,6}、(3,4,5,6}、(3,4,5.6,8)等都不是顺子给定一个包含 13 张牌的数组,如果有满足出牌规则的顺子,请输出顺子。

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

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

输入描述:

13张任意顺序的扑克牌,每张扑克牌数字用空格隔开,每张扑克牌的数字都是合法的,并且不包括大小王:2 9 J 2 3 4 K A 7 9 A 5 6不需要考虑输入为异常字符的情况

输出描述:

组成的顺子,每张扑克牌数字用空格隔开:3 4 5 6 7

示例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.

示例2

输入

2 9 J 1 0 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

示例3

输入

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

输出

No

说明

13张牌中,无法组成顺子。

题目分析:

  • 扑克牌按从小到大的顺序排列为:3, 4, 5, 6, 7, 8, 9, 10, J, Q, K, A。牌 2 不能用于顺子。

  • 顺子的规则是:至少由5张连续递增的牌组成,例如 (3, 4, 5, 6, 7)。

  • 需要找出所有可能的顺子组合,每个顺子中的牌不能重复使用。

思路

从小到大排序,然后遍历每一种牌开头的顺子情况


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

int cardToNum(const string &s)
{
    if (s == "J")
        return 11;
    else if (s == "Q")
        return 12;
    else if (s == "K")
        return 13;
    else if (s == "A")
        return 14;
    else
        return stoi(s);
}

int main()
{
    vector<pair<string, bool>> cards;
    for (int i = 0; i < 13; ++i)
    {
        std::string s;
        cin >> s;
        if (s != "2")
        {
            cards.emplace_back(s, false);
        }
    }

    // 升序排序
    sort(cards.begin(), cards.end(), [](const pair<string, bool> &s1, const pair<string, bool> &s2)
         { return cardToNum(s1.first) < cardToNum(s2.first); });

    vector<vector<string>> shunzis;
    for (int i = 0; i < cards.size(); i++)
    {
        vector<string> shunzi;
        vector<int> pos;
        if (cards[i].second == true)
            continue;
        pos.push_back(i);
        shunzi.push_back(cards[i].first);
        for (int j = i + 1; j < cards.size(); j++)
        {
            if (cards[j].first == shunzi.back())
            {
                continue;
            }
            else
            {
                if (cards[j].second == false && cardToNum(cards[j].first) == cardToNum(shunzi.back()) + 1)
                {
                    shunzi.push_back(cards[j].first);
                    pos.push_back(j);
                }
            }
        }
        if (shunzi.size() >= 5)
        {
            for (int k = 0; k < pos.size(); k++)
            {
                cards[pos[k]].second = true;
            }
            shunzis.push_back(shunzi);
        }
    }

    for (int i = 0; i < shunzis.size(); i++)
    {
        for (int j = 0; j < shunzis[i].size(); j++)
        {
            cout << shunzis[i][j] << " ";
        }
        cout << endl;
    }
    if(shunzis.size() == 0)
    {
        std::cout << "No" << std::endl;
    }
    return 0;
}