>Link
luogu P7555
>Description
>解题思路
暴力题,深搜处理,可以暴力判断井字棋盘是否获胜
优化:
用
v
i
s
i
,
j
,
k
vis_{i,j,k}
visi,j,k表示走到
(
i
,
j
)
(i,j)
(i,j),井字棋状态为
k
k
k的情况是否走过
状态:
3
∗
3
3*3
3∗3的棋盘,
0
0
0表示没填数,
1
1
1表示填
M
M
M,
2
2
2表示填
O
O
O,暴力求出棋盘的状态
注意答案的判重!!
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 30
using namespace std;
const int xxx[4] = {-1, 0, 0, 1}, yyy[4] = {0, -1, 1, 0};
struct node
{
int c, x, y;
} a[N][N];
int n, ans, sum, p[10][10], SX, SY;
string s;
bool vis[N][N][20000], kk[20000];
int getk ()
{
int ret = 0;
for (int i = 1; i <= 3; i++)
for (int j = 1; j <= 3; j++)
ret = ret * 3 + p[i][j];
return ret;
}
bool check ()
{
if (p[1][1] == 1 && p[1][2] == 2 && p[1][3] == 2) return 1;
if (p[1][1] == 2 && p[1][2] == 2 && p[1][3] == 1) return 1;
if (p[2][1] == 1 && p[2][2] == 2 && p[2][3] == 2) return 1;
if (p[2][1] == 2 && p[2][2] == 2 && p[2][3] == 1) return 1;
if (p[3][1] == 1 && p[3][2] == 2 && p[3][3] == 2) return 1;
if (p[3][1] == 2 && p[3][2] == 2 && p[3][3] == 1) return 1;
if (p[1][1] == 1 && p[2][1] == 2 && p[3][1] == 2) return 1;
if (p[1][1] == 2 && p[2][1] == 2 && p[3][1] == 1) return 1;
if (p[1][2] == 1 && p[2][2] == 2 && p[3][2] == 2) return 1;
if (p[1][2] == 2 && p[2][2] == 2 && p[3][2] == 1) return 1;
if (p[1][3] == 1 && p[2][3] == 2 && p[3][3] == 2) return 1;
if (p[1][3] == 2 && p[2][3] == 2 && p[3][3] == 1) return 1;
if (p[1][1] == 1 && p[2][2] == 2 && p[3][3] == 2) return 1;
if (p[1][1] == 2 && p[2][2] == 2 && p[3][3] == 1) return 1;
if (p[1][3] == 1 && p[2][2] == 2 && p[3][1] == 2) return 1;
if (p[1][3] == 2 && p[2][2] == 2 && p[3][1] == 1) return 1;
return 0;
}
void dfs (int x, int y)
{
int k = getk ();
if (vis[x][y][k]) return;
vis[x][y][k] = 1;
if (!kk[k])
if (check ())
{
kk[k] = 1;
ans++;
return;
}
if (kk[k]) return;
for (int i = 0; i < 4; i++)
{
int xx = x + xxx[i], yy = y + yyy[i];
if (xx < 0 || yy < 0 || xx > n || yy > n) continue;
if (a[xx][yy].c == 0) continue;
int px = a[xx][yy].x, py = a[xx][yy].y;
int last = p[px][py];
if (a[xx][yy].c > 1)
if (!p[px][py]) p[px][py] = a[xx][yy].c - 1;
dfs (xx, yy);
p[px][py] = last;
}
}
int main()
{
scanf ("%d", &n);
for (int i = 1; i <= n; i++)
{
cin >> s;
s = " " + s;
for (int j = 1, k = 1; j <= n * 3; j += 3, k++)
{
if (s[j] == 'B') SX = i, SY = k, a[i][k].c = 1;
if (s[j] == '#') a[i][k].c = 0;
if (s[j] == '.') a[i][k].c = 1;
if (s[j] == 'M')
a[i][k] = (node){2, s[j + 1] - '0', s[j + 2] - '0'};
if (s[j] == 'O')
a[i][k] = (node){3, s[j + 1] - '0', s[j + 2] - '0'};
}
}
dfs (SX, SY);
printf ("%d", ans);
return 0;
}