#include <bits/stdc++.h>
#define ll long long
#define ld long double
const int MAX_N = 8;
int T[MAX_N+3][MAX_N+3];
int n, m, k;
int bin[MAX_N * MAX_N+3][MAX_N+3];
void calc_bin() {
bin[0][0] = 1;
for (int i = 1; i <= n*m; i++) {
bin[i][0] = 1;
for (int j = 1; j <= 7; j++)
bin[i][j] = bin[i-1][j-1] + bin[i-1][j];
}
}
ll line(int l) {
if (l == 1) return 0;
if (l == 2) return 2;
ll edge, rest; edge = rest = 0;
edge = bin[l-2][k-1];
rest = bin[l-3][k-1] * 2;
if (k >= 2) rest += 2 * bin[l-3][k-2];
return edge * 2 + rest * (l-2);
}
ll calc_num_of_edges() {
ll M = 0;
if (n == 1) return line(m);
else if (m == 1) return line(n);
// n, m >= 2
ll corner, edge, rest; corner = edge = rest = 0;
// corner
for (int j = 0; j <= std::min(k-1, 1); j++)
corner += bin[2][j] * bin[n*m-3][k-j-1] * (2 - j);
// edge
if (n >= 3 || m >= 3) {
for (int j = 0; j <= std::min(k-1, 2); j++)
edge += bin[3][j] * bin[n*m-4][k-j-1] * (3 - j);
}
// rest
if (n >= 3 && m >= 3) {
for (int j = 0; j <= std::min(k-1, 3); j++)
rest += bin[4][j] * bin[n*m-5][k-j-1] * (4 - j);
}
// std::cout << "corner = " << corner << "\n";
// std::cout << "edge = " << edge << "\n";
// std::cout << "rest = " << rest << "\n";
M = (corner * 4) + (edge * ((m-2)*2 + (n-2)*2)) + (rest * ((n-2)*(m-2)));
return M;
}
ll calc_deg_of_T() {
ll D = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (T[i][j]) {
if (i > 0 && !T[i-1][j]) D++;
if (i < n-1 && !T[i+1][j]) D++;
if (j > 0 && !T[i][j-1]) D++;
if (j < m-1 && !T[i][j+1]) D++;
}
}
}
return D;
}
int main() {
std::ios_base::sync_with_stdio(0); std::cin.tie(NULL);
std::cin >> n >> m;
calc_bin();
int X, Y; X = Y = 0;
for (int i = 0; i < n; i++) {
std::string s; std::cin >> s;
for (int j = 0; j < s.length(); j++) {
if (s[j] == 'O' && (i%2) == (j%2)) X++;
if (s[j] == 'O') k++;
}
}
int kk = 0;
for (int i = 0; i < n; i++) {
std::string s; std::cin >> s;
for (int j = 0; j < s.length(); j++) {
if (s[j] == 'O' && (i%2) == (j%2)) Y++;
if (s[j] == 'O') { T[i][j] = 1; kk++; }
}
}
if ((X%2) != (Y%2) || k != kk) std::cout << "0\n";
else {
ld M = calc_num_of_edges();
M /= (ld)(2);
ld L = calc_deg_of_T();
// std::cout << "M = " << M << "\n";
// std::cout << "L = " << L << "\n";
std::cout << std::setprecision(15) << std::fixed << (L/M) << "\n";
}
}
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | #include <bits/stdc++.h> #define ll long long #define ld long double const int MAX_N = 8; int T[MAX_N+3][MAX_N+3]; int n, m, k; int bin[MAX_N * MAX_N+3][MAX_N+3]; void calc_bin() { bin[0][0] = 1; for (int i = 1; i <= n*m; i++) { bin[i][0] = 1; for (int j = 1; j <= 7; j++) bin[i][j] = bin[i-1][j-1] + bin[i-1][j]; } } ll line(int l) { if (l == 1) return 0; if (l == 2) return 2; ll edge, rest; edge = rest = 0; edge = bin[l-2][k-1]; rest = bin[l-3][k-1] * 2; if (k >= 2) rest += 2 * bin[l-3][k-2]; return edge * 2 + rest * (l-2); } ll calc_num_of_edges() { ll M = 0; if (n == 1) return line(m); else if (m == 1) return line(n); // n, m >= 2 ll corner, edge, rest; corner = edge = rest = 0; // corner for (int j = 0; j <= std::min(k-1, 1); j++) corner += bin[2][j] * bin[n*m-3][k-j-1] * (2 - j); // edge if (n >= 3 || m >= 3) { for (int j = 0; j <= std::min(k-1, 2); j++) edge += bin[3][j] * bin[n*m-4][k-j-1] * (3 - j); } // rest if (n >= 3 && m >= 3) { for (int j = 0; j <= std::min(k-1, 3); j++) rest += bin[4][j] * bin[n*m-5][k-j-1] * (4 - j); } // std::cout << "corner = " << corner << "\n"; // std::cout << "edge = " << edge << "\n"; // std::cout << "rest = " << rest << "\n"; M = (corner * 4) + (edge * ((m-2)*2 + (n-2)*2)) + (rest * ((n-2)*(m-2))); return M; } ll calc_deg_of_T() { ll D = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (T[i][j]) { if (i > 0 && !T[i-1][j]) D++; if (i < n-1 && !T[i+1][j]) D++; if (j > 0 && !T[i][j-1]) D++; if (j < m-1 && !T[i][j+1]) D++; } } } return D; } int main() { std::ios_base::sync_with_stdio(0); std::cin.tie(NULL); std::cin >> n >> m; calc_bin(); int X, Y; X = Y = 0; for (int i = 0; i < n; i++) { std::string s; std::cin >> s; for (int j = 0; j < s.length(); j++) { if (s[j] == 'O' && (i%2) == (j%2)) X++; if (s[j] == 'O') k++; } } int kk = 0; for (int i = 0; i < n; i++) { std::string s; std::cin >> s; for (int j = 0; j < s.length(); j++) { if (s[j] == 'O' && (i%2) == (j%2)) Y++; if (s[j] == 'O') { T[i][j] = 1; kk++; } } } if ((X%2) != (Y%2) || k != kk) std::cout << "0\n"; else { ld M = calc_num_of_edges(); M /= (ld)(2); ld L = calc_deg_of_T(); // std::cout << "M = " << M << "\n"; // std::cout << "L = " << L << "\n"; std::cout << std::setprecision(15) << std::fixed << (L/M) << "\n"; } } |
English