在斗地主扑克牌游戏中, 扑克牌由小到大的顺序为: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。

输入描述

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

1

输出

3 4 5 6 7

1

说明

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

示例2

输入:

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

1

输出:

3 4 5 6 7

9 10 J Q K A

12

说明

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

1

输出:

No

1

说明

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

解题思路

这个问题涉及解析一个包含13张扑克牌的数组,目的是识别出所有符合条件的有效顺子。顺子定义为至少包含5张按牌面大小顺序连续的扑克牌,不包括牌面为“2”的牌。

题目描述存在不明确之处,未具体说明是要求解最多数量的顺子,还是单个最长的顺子。

考虑以下示例:

4 5 6 7 8 6 7 8 9 10

1

如果目标是找到数量最多的顺子,答案将是两个独立的顺子:【4 5 6 7 8】和【6 7 8 9 10】。

如果目标是找到单个最长的顺子,答案则是【4 5 6 7 8 9 10】。

此外,如果【数量最多的顺子】,尽管【5 6 7 8 9】也是一个有效顺子,但在按照第二个示例的选择规则,它不是答案。这表明题目可能更倾向于寻找最长的顺子,且实际机考按照最长的去找,通过率高于数量最多。

点击查看代码

#include

#include

#include

// 定义扑克牌与其数值的映射关系结构体

typedef struct {

char card[3]; // 扑克牌面(考虑到"10"有两个字符,所以数组大小为3)

int value; // 对应的数值

} CardMap;

// 扑克牌面到数值的映射表

CardMap card_to_number[] = {

{"3", 3}, {"4", 4}, {"5", 5}, {"6", 6}, {"7", 7}, {"8", 8}, {"9", 9},

{"10", 10}, {"J", 11}, {"Q", 12}, {"K", 13}, {"A", 14}, {"2", 16}

};

int card_map_size = sizeof(card_to_number) / sizeof(card_to_number[0]);

// 用于比较扑克牌的函数

int compare_cards(const void *a, const void *b) {

const char *card1 = *(const char **)a;

const char *card2 = *(const char **)b;

int value1 = 0, value2 = 0;

for (int i = 0; i < card_map_size; ++i) {

if (strcmp(card_to_number[i].card, card1) == 0) {

value1 = card_to_number[i].value;

}

if (strcmp(card_to_number[i].card, card2) == 0) {

value2 = card_to_number[i].value;

}

}

return value1 - value2;

}

int main(){

char input[100]; // 存储输入字符串

char *cards[20]; // 存储分割后的扑克牌字符串指针

int count = 0; // 扑克牌数量

// 读取一行输入

fgets(input, sizeof(input), stdin);

input[strcspn(input, "\n")] = 0; // 移除换行符

// 分割输入字符串

char *token = strtok(input, " ");

while (token != NULL) {

cards[count++] = token;

token = strtok(NULL, " ");

}

// 对扑克牌进行排序

qsort(cards, count, sizeof(char *), compare_cards);

// 动态分配二维数组来存储可能的顺子序列

char **straights[count];

int lengths[count]; // 存储每个顺子的长度

for (int i = 0; i < count; ++i) {

straights[i] = malloc(count * sizeof(char *));

straights[i][0] = cards[i];

lengths[i] = 1;

}

int num_straights = count;

// 生成顺子序列

for (int i = 0; i < count; ++i) {

for (int j = 0; j < num_straights; ++j) {

if (compare_cards(&cards[i], &straights[j][lengths[j] - 1]) == 1) {

straights[j][lengths[j]++] = cards[i];

break;

}

}

}

// 输出长度至少为5的顺子序列

int found = 0;

for (int i = 0; i < num_straights; ++i) {

if (lengths[i] >= 5) {

found = 1;

for (int j = 0; j < lengths[i]; ++j) {

printf("%s ", straights[i][j]);

}

printf("\n");

}

free(straights[i]);

}

if (!found) {

printf("No\n");

}

return 0;

}