#include <iostream>
#include <vector>
#include <sstream>
#include <cstring>
using namespace std;
bool backtrack(int counts[9]) {
int i = 0;
while (i < 9 && counts[i] == 0) {
i++;
}
if (i >= 9) {
return true;
}
// 尝试刻子
if (counts[i] >= 3) {
counts[i] -= 3;
bool res = backtrack(counts);
counts[i] += 3;
if (res) {
return true;
}
}
// 尝试顺子
if (i + 2 < 9 && counts[i] >= 1 && counts[i + 1] >= 1 && counts[i + 2] >= 1) {
counts[i]--;
counts[i + 1]--;
counts[i + 2]--;
bool res = backtrack(counts);
counts[i]++;
counts[i + 1]++;
counts[i + 2]++;
if (res) {
return true;
}
}
return false;
}
bool checkGroup(int counts[9]) {
int temp[9];
memcpy(temp, counts, sizeof(temp));
return backtrack(temp);
}
bool canHu(int m[9], int s[9], int p[9]) {
// 尝试所有可能的将牌
for (int color = 0; color < 3; color++) {
for (int i = 0; i < 9; i++) {
// 创建三个花色的拷贝数组
int m_copy[9], s_copy[9], p_copy[9];
memcpy(m_copy, m, sizeof(m_copy));
memcpy(s_copy, s, sizeof(s_copy));
memcpy(p_copy, p, sizeof(p_copy));
// 确定当前尝试的花色
int* cnt;
switch (color) {
case 0: cnt = m_copy; break;
case 1: cnt = s_copy; break;
case 2: cnt = p_copy; break;
}
// 判断是否有两张牌可以作为将牌
if (cnt[i] >= 2) {
// 扣除将牌
cnt[i] -= 2;
// 检查每个花色的拷贝数组是否都能组成正确的组合
bool valid = checkGroup(m_copy) && checkGroup(s_copy) && checkGroup(p_copy);
// 如果有效,返回true
if (valid) {
return true;
}
}
}
}
return false;
}
vector<string> getWaitingTiles(int m_counts[9], int s_counts[9], int p_counts[9]) {
vector<string> result;
for (int color = 0; color < 3; color++) {
string suit;
switch (color) {
case 0: suit = "m"; break;
case 1: suit = "s"; break;
case 2: suit = "p"; break;
}
for (int num = 1; num <= 9; num++) {
int idx = num - 1;
int current_count;
switch (color) {
case 0: current_count = m_counts[idx]; break;
case 1: current_count = s_counts[idx]; break;
case 2: current_count = p_counts[idx]; break;
}
if (current_count < 4) {
int m_temp[9], s_temp[9], p_temp[9];
memcpy(m_temp, m_counts, sizeof(m_temp));
memcpy(s_temp, s_counts, sizeof(s_temp));
memcpy(p_temp, p_counts, sizeof(p_temp));
switch (color) {
case 0: m_temp[idx]++; break;
case 1: s_temp[idx]++; break;
case 2: p_temp[idx]++; break;
}
if (canHu(m_temp, s_temp, p_temp)) {
result.push_back(to_string(num) + suit);
}
}
}
}
return result;
}
int main() {
int m_counts[9] = { 0 };
int s_counts[9] = { 0 };
int p_counts[9] = { 0 };
string line;
getline(cin, line);
istringstream iss(line);
string token;
while (iss >> token) {
if (token.size() < 2) continue;
char num_char = token[0];
char suit = token[1];
int num = num_char - '0';
if (num < 1 || num > 9) continue;
int idx = num - 1;
switch (suit) {
case 'm': m_counts[idx]++; break;
case 's': s_counts[idx]++; break;
case 'p': p_counts[idx]++; break;
}
}
vector<string> waiting = getWaitingTiles(m_counts, s_counts, p_counts);
for (size_t i = 0; i < waiting.size(); i++) {
if (i > 0) cout << " ";
cout << waiting[i];
}
cout << endl;
return 0;
}
例: