#include<bits/stdc++.h>
#define int long long
#define P 12345678
using namespace std;
int n, m;
int x[16], y[16];
int tot, g[1024], f[64][1024];
bitset<8> tmp[16];
void dfs(int d, int s){
if(d>=tot) {
int cnt=n*m;
for(int i=0; i<n; ++i)
for(int j=0; j<m; ++j)
if(tmp[i][j]) --cnt;
g[s]=cnt;
return;
}
dfs(d+1, s);
for(int i=max(x[d+1]-1, 0ll); i<=min(x[d+1]+1, n-1); ++i)
for(int j=max(y[d+1]-1, 0ll); j<=min(y[d+1]+1, m-1); ++j)
tmp[i][j]=1;
dfs(d+1, s^(1<<d));
for(int i=max(x[d+1]-1, 0ll); i<=min(x[d+1]+1, n-1); ++i)
for(int j=max(y[d+1]-1, 0ll); j<=min(y[d+1]+1, m-1); ++j)
tmp[i][j]=0;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i=0; i<n; ++i) {
string s;
cin >> s;
for(int j=0; j<m; ++j)
if(s[j]=='X')
x[++tot]=i, y[tot]=j;
}
dfs(0, (1<<tot)-1);
f[0][0]=1;
for(int i=1; i<=n*m; ++i)
for(int j=0; j<(1<<tot); ++j) {
f[i][j]=f[i-1][j]*max(g[j]-i+1, 0ll)%P;
for(int k=0; k<tot; ++k)
if((j>>k)&1)
f[i][j]=(f[i][j]+f[i-1][j-(1<<k)])%P;
}
cout << f[n*m][(1<<tot)-1] << '\n';
return 0;
}
f[i][j]
表示从小到大填,已经填完1->i
,局部最小点的填写情况为j
的方案数.
g[i]
代表局部最小点在i
状态下能填的位置数量(就是不被 未被填的局部最小点 九方格所覆盖的位置数量)
那位大佬帮忙看看思路有什么问题. QwQ