URAL - 1627 Join
Businessman Petya recently bought a new house. This house has one floor with n × m square rooms, placed in rectangular lattice. Some rooms are pantries and the other ones are bedrooms. Now he wants to join all bedrooms with doors in such a way that there will be exactly one way between any pair of them. He can make doors only between neighbouring bedrooms (i.e. bedrooms having a common wall). Now he wants to count the number of different ways he can do it.
Input
First line contains two integers n and m (1 ≤ n, m ≤ 9) — the number of lines and columns in the lattice. Next n lines contain exactly m characters representing house map, where "." means bedroom and "*" means pantry. It is guaranteed that there is at least one bedroom in the house.
Output
Output the number of ways to join bedrooms modulo 10 9.
Example
input | output |
---|---|
2 2 .. .. | 4 |
2 2 *. .* | 0 |
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 100 + 10;
const int maxm = 1010025;
const int INF = 0x3f3f3f3f;
const int mod = 1e9;
const double eps = 1e-8;
#define type long long
int n,m;
int d[maxn];
int g[maxn][maxn];
type c[maxn][maxn];
type det(type a[][maxn],int n)
{
type ret=1;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
while(a[j][i])
{
type t=a[i][i]/a[j][i];
for(int k=i;k<=n;k++)
a[i][k]=(((a[i][k]-a[j][k]*t)%mod)+mod)%mod;
for(int k=i;k<=n;k++)
swap(a[i][k],a[j][k]);
ret=-ret;
}
}
if(a[i][i]==0) return 0;
ret=(((ret*a[i][i])%mod)+mod)%mod;
}
if(ret<0) ret=-ret;
return ret%mod;
}
type num_st(int n)
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
{
if(i == j) c[i][j] = d[i];
else c[i][j] = -g[i][j];
}
/*
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
printf("%lld%c",c[i][j],j == n ? '\n' : ' ');
*/
return det(c,n-1);
}
typedef pair<int,int> P;
map <P,int> mp;
int tot = 0;
string s[10];
int fx[4] = {0,0,1,-1};
int fy[4] = {1,-1,0,0};
bool check(int x, int y)
{
if(x < 0 || y < 0 || x >= n || y >= m) return false;
if(s[x][y] == '.') return true;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i = 0; i < n; i++)
{
cin >> s[i];
for(int j = 0; j < m; j++)
if(s[i][j] == '.') mp[P(i,j)] = ++tot;
}
memset(g,0,sizeof(g));
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
{
if(s[i][j] == '.')
for(int k = 0; k < 4; k++)
{
int di = i + fx[k];
int dj = j + fy[k];
if(check(di,dj))
{
int u = mp[P(i,j)];
int v = mp[P(di,dj)];
g[u][v] = g[v][u] = 1;
}
}
}
for(int i = 1; i <= tot; i++)
for(int j = 1; j <= tot; j++)
if(i != j) d[i] += g[i][j];
type ans = num_st(tot);
printf("%lld\n",ans);
return 0;
}