#include <bits/stdc++.h> using namespace std; const int N = 65, M = 9; long long binom[N][N]; void prepareBinom() { for (int i = 0; i < N; i++) { binom[i][0] = 1; } for (int i = 1; i < N; i++) for (int j = 1; j <= min(i, M); j++) { binom[i][j] = binom[i-1][j] + binom[i-1][j-1]; } } pair <int,int> getParityAndNumPawns(int n, int m, vector <vector<bool>> &tab) { int par = 0, numPawns = 0; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) { if (tab[i][j]) { numPawns++; par ^= (i + j) % 2; } } return {par, numPawns}; } int getDegree(int n, int m, vector <vector<bool>> &tab) { int dx[] = {0, 1, 0, -1}; int dy[] = {1, 0, -1, 0}; int deg = 0; for (int x = 0; x < n; x++) for (int y = 0; y < m; y++) { if (tab[x][y]) { for (int dir = 0; dir < 4; dir++) { int nx = x + dx[dir], ny = y + dy[dir]; if (nx >= 0 && nx < n && ny >= 0 && ny < m && !tab[nx][ny]) { deg++; } } } } return deg; } long double solve(int n, int m, vector <vector <vector<bool>>> &tab) { auto [parStart, numPawns] = getParityAndNumPawns(n, m, tab[0]); auto [parEnd, _] = getParityAndNumPawns(n, m, tab[1]); if (parStart != parEnd) { return 0.0; } int numSquares = n * m; int numWaysDomino = (n - 1) * m + n * (m - 1); int degree = getDegree(n, m, tab[1]); long long numEdges = numWaysDomino * binom[numSquares - 2][numPawns - 1]; return (long double) degree / numEdges; } int main() { ios_base::sync_with_stdio(false); prepareBinom(); cout << setprecision(16) << fixed; int n, m; cin >> n >> m; vector <vector <vector<bool>>> tab(2, vector <vector<bool>> (n, vector <bool> (m))); for (int t = 0; t < 2; t++) { for (int i = 0; i < n; i++) { string s; cin >> s; for (int j = 0; j < m; j++) { tab[t][i][j] = s[j] == 'O'; } } } cout << solve(n, m, tab); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #include <bits/stdc++.h> using namespace std; const int N = 65, M = 9; long long binom[N][N]; void prepareBinom() { for (int i = 0; i < N; i++) { binom[i][0] = 1; } for (int i = 1; i < N; i++) for (int j = 1; j <= min(i, M); j++) { binom[i][j] = binom[i-1][j] + binom[i-1][j-1]; } } pair <int,int> getParityAndNumPawns(int n, int m, vector <vector<bool>> &tab) { int par = 0, numPawns = 0; for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) { if (tab[i][j]) { numPawns++; par ^= (i + j) % 2; } } return {par, numPawns}; } int getDegree(int n, int m, vector <vector<bool>> &tab) { int dx[] = {0, 1, 0, -1}; int dy[] = {1, 0, -1, 0}; int deg = 0; for (int x = 0; x < n; x++) for (int y = 0; y < m; y++) { if (tab[x][y]) { for (int dir = 0; dir < 4; dir++) { int nx = x + dx[dir], ny = y + dy[dir]; if (nx >= 0 && nx < n && ny >= 0 && ny < m && !tab[nx][ny]) { deg++; } } } } return deg; } long double solve(int n, int m, vector <vector <vector<bool>>> &tab) { auto [parStart, numPawns] = getParityAndNumPawns(n, m, tab[0]); auto [parEnd, _] = getParityAndNumPawns(n, m, tab[1]); if (parStart != parEnd) { return 0.0; } int numSquares = n * m; int numWaysDomino = (n - 1) * m + n * (m - 1); int degree = getDegree(n, m, tab[1]); long long numEdges = numWaysDomino * binom[numSquares - 2][numPawns - 1]; return (long double) degree / numEdges; } int main() { ios_base::sync_with_stdio(false); prepareBinom(); cout << setprecision(16) << fixed; int n, m; cin >> n >> m; vector <vector <vector<bool>>> tab(2, vector <vector<bool>> (n, vector <bool> (m))); for (int t = 0; t < 2; t++) { for (int i = 0; i < n; i++) { string s; cin >> s; for (int j = 0; j < m; j++) { tab[t][i][j] = s[j] == 'O'; } } } cout << solve(n, m, tab); return 0; } |