#include <bits/stdc++.h>
using namespace std;
int height, width;
int startBlacks = 0;
int endBlacks = 0;
vector<vector<bool>> endPosition;
vector<pair<int, int>> endPawns;
double binomial(int n, int k) {
double result = 1;
int i = n;
while (i > n-k) {
result *= i;
i--;
}
i = 2;
while (i <= k) {
result /= i;
i++;
}
return result;
}
void read() {
cin >> height >> width;
char field;
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
cin >> field;
if (field == 'O' && (i - j) % 2 == 0) {
startBlacks++;
}
}
}
for (int i = 0; i < height; ++i) {
vector<bool> row;
for (int j = 0; j < width; ++j) {
cin >> field;
row.push_back(field == 'O');
if (field == 'O') {
endPawns.emplace_back(i, j);
if ((i - j) % 2 == 0) {
endBlacks++;
}
}
}
endPosition.push_back(row);
}
}
int getEndPositionMoves() {
int result = 0;
for (auto pawn: endPawns) {
if (pawn.first > 0 && !endPosition[pawn.first - 1][pawn.second]) {
result++;
}
if (pawn.second > 0 && !endPosition[pawn.first][pawn.second - 1]) {
result++;
}
if (pawn.first + 1 < height && !endPosition[pawn.first + 1][pawn.second]) {
result++;
}
if (pawn.second + 1 < width && !endPosition[pawn.first][pawn.second + 1]) {
result++;
}
}
return result;
}
double getAllMoves() {
int singleMoves;
if (min(height, width) == 1) {
singleMoves = 2 * max(height, width) - 2;
} else {
singleMoves = 8 + 6 * (height + width - 4) + 4 * (height - 2) * (width - 2);
}
return singleMoves * binomial(width * height - 2, (int) endPawns.size() - 1);
}
string format(double nominator, double denominator) {
stringstream ss;
ss.precision(16);
ss << fixed;
ss << nominator / denominator;
string result = ss.str();
if (result.find('.') != string::npos) {
result = result.substr(0, result.find_last_not_of('0') + 1);
if (result.find('.') == result.size() - 1) {
result = result.substr(0, result.size() - 1);
}
}
return result;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
read();
if (startBlacks % 2 != endBlacks % 2) {
cout << 0 << endl;
return 0;
}
double nominator = 2.0 * getEndPositionMoves();
double denominator = getAllMoves();
cout << format(nominator, denominator) << endl;
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | #include <bits/stdc++.h> using namespace std; int height, width; int startBlacks = 0; int endBlacks = 0; vector<vector<bool>> endPosition; vector<pair<int, int>> endPawns; double binomial(int n, int k) { double result = 1; int i = n; while (i > n-k) { result *= i; i--; } i = 2; while (i <= k) { result /= i; i++; } return result; } void read() { cin >> height >> width; char field; for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { cin >> field; if (field == 'O' && (i - j) % 2 == 0) { startBlacks++; } } } for (int i = 0; i < height; ++i) { vector<bool> row; for (int j = 0; j < width; ++j) { cin >> field; row.push_back(field == 'O'); if (field == 'O') { endPawns.emplace_back(i, j); if ((i - j) % 2 == 0) { endBlacks++; } } } endPosition.push_back(row); } } int getEndPositionMoves() { int result = 0; for (auto pawn: endPawns) { if (pawn.first > 0 && !endPosition[pawn.first - 1][pawn.second]) { result++; } if (pawn.second > 0 && !endPosition[pawn.first][pawn.second - 1]) { result++; } if (pawn.first + 1 < height && !endPosition[pawn.first + 1][pawn.second]) { result++; } if (pawn.second + 1 < width && !endPosition[pawn.first][pawn.second + 1]) { result++; } } return result; } double getAllMoves() { int singleMoves; if (min(height, width) == 1) { singleMoves = 2 * max(height, width) - 2; } else { singleMoves = 8 + 6 * (height + width - 4) + 4 * (height - 2) * (width - 2); } return singleMoves * binomial(width * height - 2, (int) endPawns.size() - 1); } string format(double nominator, double denominator) { stringstream ss; ss.precision(16); ss << fixed; ss << nominator / denominator; string result = ss.str(); if (result.find('.') != string::npos) { result = result.substr(0, result.find_last_not_of('0') + 1); if (result.find('.') == result.size() - 1) { result = result.substr(0, result.size() - 1); } } return result; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); read(); if (startBlacks % 2 != endBlacks % 2) { cout << 0 << endl; return 0; } double nominator = 2.0 * getEndPositionMoves(); double denominator = getAllMoves(); cout << format(nominator, denominator) << endl; return 0; } |
English