原题链接:https://ac.nowcoder.com/acm/contest/12548/K
题意
麻将的规则就直接略过了,题目是当前有14张牌,你可以打出一张,然后输出听了哪些牌,询问方案并输出
分析
直接暴力枚举所有的牌丢弃,然后从牌池中枚举一张牌摸进来,判断是否胡牌。
有一些细节需要处理
-
注意在判断胡牌时需要枚举雀头,注意这里可以剪枝(牌数大于2时)。
-
最后注意输出时要按照一定的顺序,本题不是spj
最后计算一波时间复杂度 T ∗ 1 4 2 ∗ 3 4 2 T * 14 ^ 2 * 34 ^ 2 T∗142∗342
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <bitset>
#include <map>
#include <set>
#include <stack>
#include <queue>
//#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define re register
typedef long long ll;
typedef pair<ll, ll> PII;
typedef unsigned long long ull;
const int N = 1e5 + 10, M = 1e6 + 5, INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
int mp[5][15], backup[5][15], backup1[5][15];
char type[15];
int id[15], vis[5][15];
struct node {
int c;
int x;
};
bool judge() {
memcpy(backup1, backup, sizeof backup);
int shunzi = 0, san = 0;
for (int i = 1; i <= 7; i++) {
if (backup1[4][i] == 3) san++, backup1[4][i] -= 3;
else if (backup1[4][i] && backup1[4][i] != 3) return false;
}
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 9; j++) {
if (!backup1[i][j]) continue;
if (backup1[i][j] > 2) backup1[i][j] -= 3, san += 1;
if (!backup1[i][j]) continue;
if (min(backup1[i][j+1], backup1[i][j+2]) < backup1[i][j]) return false;
shunzi += backup1[i][j];
backup1[i][j+1] -= backup1[i][j];
backup1[i][j+2] -= backup1[i][j];
backup1[i][j] = 0;
}
}
if (san + shunzi == 4) return true;
else return false;
}
bool check() {
memcpy(backup, mp, sizeof mp);
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= (i == 4 ? 7 : 9) ; j++) {
if (backup[i][j] >= 2) {
backup[i][j] -= 2;
if (judge()) return true;
backup[i][j] += 2;
}
}
}
return false;
}
void solve() {
int n; scanf("%d\n", &n);
while (n--) {
memset(mp, 0, sizeof mp);
memset(backup, 0, sizeof backup);
memset(backup1, 0, sizeof backup1);
for (int i = 1; i <= 14; i++) {
char x, y; scanf("%c%c", &x, &y);
id[i] = x-'0';
if (y == 'w') mp[1][x-'0']++, type[i] = 1;
if (y == 'b') mp[2][x-'0']++, type[i] = 2;
if (y == 's') mp[3][x-'0']++, type[i] = 3;
if (y == 'z') mp[4][x-'0']++, type[i] = 4;
}
getchar();
if (check()) {
printf("Tsumo!\n");
continue;
}
vector<node> ans[5][15];
memset(vis, 0, sizeof vis);
for (int a = 1; a <= 4; a++) {
for (int b = 1; b <= (a == 4 ? 7 : 9); b++) {
if (!mp[a][b]) continue;
mp[a][b]--;
for (int k = 1; k <= 4; k++) {
for (int j = 1; j <= (k == 4 ? 7 : 9); j++) {
mp[k][j]++;
if (check()) ans[a][b].push_back({k, j});
mp[k][j]--;
}
}
mp[a][b]++;
}
}
int num = 0;
for (int a = 1; a <= 4; a++) {
for (int b = 1; b <= (b == 4 ? 7 : 9); b++) {
num += (ans[a][b].size() != 0);
}
}
printf("%d\n", num);
for (int a = 1; a <= 4; a++) {
for (int b = 1; b <= (a == 4 ? 7 : 9); b++) {
if (!ans[a][b].size()) continue;
if (a == 1) printf("%dw ", b);
if (a == 2) printf("%db ", b);
if (a == 3) printf("%ds ", b);
if (a == 4) printf("%dz ", b);
for (auto it : ans[a][b]) {
if (it.c == 1) printf("%dw", it.x);
if (it.c == 2) printf("%db", it.x);
if (it.c == 3) printf("%ds", it.x);
if (it.c == 4) printf("%dz", it.x);
}
printf("\n");
}
}
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
solve();
return 0;
}