在斗地主扑克牌游戏中, 扑克牌由小到大的顺序为: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 <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义扑克牌与其数值的映射关系结构体
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;
}