CF71D Solitaire

· · 题解

传送门

暴力模拟水题

思路如下:

读入数据,记录王的数量和位置;

枚举没有出现过的牌,把王替换掉,然后 \operatorname{check}

然而 \operatorname{check} 有亿点麻烦:

用四重循环枚举两个正方形的左上角位置,用朴素方法判断是否花色一样或是数字互不相同,如果满足就输出答案( \operatorname{end}

```cpp void check() { int cnt1 = -5, cnt2 = -5; rep(x, n - 2) { rep(y, m - 2) { if (ok) return; if (x < cnt1 + 3 && y < cnt2 + 3) continue; bool suc = 1; char ch; forr(i, x, x + 3) { forr(j, y, y + 3) { if (i == x && j == y) ch = s[i][j][1]; else if (ch != s[i][j][1]) suc = 0; } } if (suc == 1) { if (cnt1 == -5) { cnt1 = x, cnt2 = y; } else end(cnt1, cnt2, x, y); continue; } if (ok) return; suc = 1; map<char, bool> mc; forr(i, x, x + 3) { forr(j, y, y + 3) { if (mc[s[i][j][0]]) suc = 0; mc[s[i][j][0]] = 1; } } if (suc == 1) { if (cnt1 == -5) { cnt1 = x, cnt2 = y; } else end(cnt1, cnt2, x, y); } if (ok) return; } } } ``` 最后要注意输出格式,不要漏空格 完整代码: ```cpp #include <bits/stdc++.h> using namespace std; #define ll long long #define db double #define ld long double #define forr(i, a, n) for (int i = a; i < n; i++) #define rep(i, n) forr(i, 0, n) #define repp(i, n) forr(i, 1, n + 1) #define foreach(it, t) for (__typeof(t.begin()) it = t.begin(); it != t.end(); it++) #define pb push_back #define mp make_pair #define all(a) a.begin(), a.end() #define init(a, i) memset(a, i, sizeof(a)) #define pii pair<int, int> #define vvi vector<vector<int>> #define MAXN 0x3f3f3f3f string a[] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"}; string b[] = {"C", "D", "H", "S"}; int n, m; int num = 0; string st, st1, st2; string s[20][20]; map<string, int> mm; int jx1 = -1, jy1 = -1, jx2 = -1, jy2 = -1; int sim; bool ok = 0; void end(int x1, int y1, int x2, int y2) { cout << "Solution exists.\n"; if (num == 0) { cout << "There are no jokers.\n"; } if (num == 1) { cout << "Replace J" << sim << " with " << st << ".\n"; } if (num == 2) { cout << "Replace J1 with " << st1 << " and J2 with " << st2 << ".\n"; } cout << "Put the first square to (" << x1 + 1 << ", " << y1 + 1 << ").\n"; cout << "Put the second square to (" << x2 + 1 << ", " << y2 + 1 << ").\n"; ok = 1; } void check() { int cnt1 = -5, cnt2 = -5; rep(x, n - 2) { rep(y, m - 2) { if (ok) return; if (x < cnt1 + 3 && y < cnt2 + 3) continue; bool suc = 1; char ch; forr(i, x, x + 3) { forr(j, y, y + 3) { if (i == x && j == y) ch = s[i][j][1]; else if (ch != s[i][j][1]) suc = 0; } } if (suc == 1) { if (cnt1 == -5) { cnt1 = x, cnt2 = y; } else end(cnt1, cnt2, x, y); continue; } if (ok) return; suc = 1; map<char, bool> mc; forr(i, x, x + 3) { forr(j, y, y + 3) { if (mc[s[i][j][0]]) suc = 0; mc[s[i][j][0]] = 1; } } if (suc == 1) { if (cnt1 == -5) { cnt1 = x, cnt2 = y; } else end(cnt1, cnt2, x, y); } if (ok) return; } } } void solve() { cin >> n >> m; rep(i, n) rep(j, m) { cin >> s[i][j]; if (isdigit(s[i][j][1])) { num++; sim = s[i][j][1] - '0'; if (sim == 1) { jx1 = i, jy1 = j; } else { jx2 = i, jy2 = j; } } else mm[s[i][j]] = 1; } if (num == 0) check(); if (num == 1) { rep(i, 13) { rep(j, 4) { if (ok) return; st = "" + a[i] + b[j]; if (!mm[st]) { mm[st] = 1; if (sim == 1) s[jx1][jy1] = st; else s[jx2][jy2] = st; check(); mm[st] = 0; } } } } if (num == 2) { rep(i, 13) { rep(j, 4) { st1 = "" + a[i] + b[j]; if (mm[st1]) continue; mm[st1] = 1; s[jx1][jy1] = st1; rep(ii, 13) { rep(jj, 4) { if (ok) return; st2 = "" + a[ii] + b[jj]; if (!mm[st2]) { mm[st2] = 1; s[jx2][jy2] = st2; check(); mm[st2] = 0; } } } mm[st1] = 0; } } } if (!ok) cout << "No solution.\n"; } int main() { int T; T = 1; //cin>>T; while (T--) solve(); return 0; } ```