←_←习得此题,对麻将便略知一二。原来“和”需要一个将、0个或者多个刻子和0个或者多个顺子,←_← 若拿到一张牌能“和“了,则称听了这张牌。
例如1S 1S 2S 2S 2S 3S 3S 3S 7S 8S 9S FA FA
只要摸到1S 4S FA其中一个就可以和了,则称手牌听了1S 4S FA
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<vector>
#include<cstring>
const char* cards[] = {
"1T","2T","3T","4T","5T","6T","7T","8T","9T",
"1S","2S","3S","4S","5S","6S","7S","8S","9S",
"1W","2W","3W","4W","5W","6W","7W","8W","9W",
"DONG","NAN","XI","BEI",
"ZHONG","FA","BAI"
};
int c[34];
int convert(char *s)
{
for (int i = 0; i<34; i++)
if (strcmp(cards[i], s) == 0)
return i;
return -1;
}
bool search(int dep)
{
for (int i = 0; i<34; i++)if (c[i] >= 3)
{
if (dep == 3)return true;
c[i] -= 3;
if (search(dep + 1))return true;
c[i] += 3;
}
for (int i = 0; i <= 24; i++)if (c[i] >= 1 && i % 9 <= 6 && c[i + 1] >= 1 && c[i + 2] >= 1)
{
if (dep == 3)return true;
c[i]--; c[i + 1]--; c[i + 2]--;
if (search(dep + 1))return true;
c[i]++; c[i + 1]++; c[i + 2]++;
}
return false;
}
bool check()
{
for (int i = 0; i<34; i++)
{
if (c[i] >= 2)
{
c[i] -= 2;
if (search(0))return true;
c[i] += 2;
}
}
return false;
}
using namespace std;
int main()
{
int mj[13]; char str[7];
bool ok; int kase = 0;
while (scanf("%s", &str) == 1)
{
ok = false;
if (str[0] == '0')break;
printf("Case %d:", ++kase);
mj[0] = convert(str);
for (int i = 1; i<13; i++) {
scanf("%s", &str); mj[i] = convert(str);
}
for (int i = 0; i<34; i++)
{
memset(c, 0, sizeof(c));
for (int j = 0; j<13; j++)
c[mj[j]]++;
if (c[i] >= 4)continue;
c[i]++;
if (check())
{
ok = true;
printf(" %s", cards[i]);
}
c[i]--;
}
if (!ok)printf(" Not ready");
printf("\n");
}
return 0;
}