CF71D Solitaire
Rushroom
·
·
题解
传送门
暴力模拟水题
思路如下:
读入数据,记录王的数量和位置;
枚举没有出现过的牌,把王替换掉,然后 \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;
}
```