题目:11210 - Chinese Mahjong
题目大意:给出十三个麻将, 问再取哪一个能胡?把所有的情况列出来,并且按照题目要求的顺序。胡的条件需要一个而且仅一个对,然后剩下要么是三个相同的,要么是三个连续的(前提是后缀相同,并且只有 T, S, W在考虑范围内)
解题思路:把要取的情况一个个枚举出来,然后dfs, 找是否加入这个可以胡就可以了,找的话就三种情况去判断一下。但是要注意:三个连续要注意需要后缀相同,我这里是把麻将转成数字,然后统计这个麻将出现的次数,所以需要些边界的判断。
代码:
#include <stdio.h> #include <string.h> const int N = 35; const char s[7][7] = {"DONG", "NAN", "XI", "BEI", "ZHONG", "FA", "BAI"}; int tile[N]; char str[N]; int handle () { if (str[0] >= '1' && str[0] <= '9') { int add; switch (str[1]) { case 'T': add = 0;break; case 'S': add = 9;break; case 'W': add = 18;break; } return add + str[0] - '0'; } else { int i; for (i = 0; i < 7; i++) if (strcmp(str, s[i]) == 0) break; return 28 + i; } } bool dfs (int k, int flag) { if (k >= 14) { if (flag) return true; return false; } for (int i = 1; i < N; i++) { if (tile[i] >= 2 && !flag) { tile[i] -= 2; if (dfs (k + 2, 1)) { tile[i] += 2; return true; } tile[i] += 2; } if (tile[i] >= 3) { tile[i] -= 3; if (dfs (k + 3, flag)) { tile[i] += 3; return true; } tile[i] += 3; } if ( (i > 7&& i < 10) || (i > 16 && i < 19) || i > 25) continue; if (tile[i] >= 1 && tile[i + 1] >= 1 && tile[i + 2] >= 1) { tile[i]--; tile[i + 1]--; tile[i + 2]--; if (dfs (k + 3, flag)) { tile[i]++; tile[i + 1]++; tile[i + 2]++; return true; } tile[i]++; tile[i + 1]++; tile[i + 2]++; } } return false; } int main () { int ans[N], k, cas = 0; while (scanf ("%s", str)) { memset (tile, 0, sizeof(tile)); k = 0; if (str[0] == '0') break; tile[handle()]++; for (int i = 0; i < 12; i++) { scanf ("%s", str); tile[handle()]++; } for (int i = 1; i < N; i++) { if (tile[i] >= 4) continue; tile[i]++; if (dfs (0, 0)) ans[k++] = i; tile[i]--; } printf ("Case %d: ", ++cas); if (!k) { printf ("Not ready\n"); continue; } for (int i = 0; i < k; i++) { if (i < k - 1) { if (ans[i] >= 1 && ans[i] <= 9) printf ("%dT ", ans[i]); else if (ans[i] >= 10 && ans[i] <= 18) printf ("%dS ", ans[i]- 9); else if (ans[i] >= 19 && ans[i] <= 27) printf ("%dW ", ans[i] - 18); else printf ("%s ", s[ans[i] - 28]); } else { if (ans[i] >= 1 && ans[i] <= 9) printf ("%dT\n", ans[i]); else if (ans[i] >= 10 && ans[i] <= 18) printf ("%dS\n", ans[i] - 9); else if (ans[i] >= 19 && ans[i] <= 27) printf ("%dW\n", ans[i] - 18); else printf ("%s\n", s[ans[i] - 28]); } } } }