#include <iostream> #include <string> #include <algorithm> #include <vector> #include <iomanip> #define LL long long #define VL vector<LL> #define VVL vector<VL> #define VVVL vector<VVL> #define PC(b) __builtin_popcount(b) using namespace std; int to_bin(int n, string &s) { int res = 0; for (int i = 0; i < n; ++i) { res <<= 1; if (s[i] == 'O') ++res; } return res; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; int invariant1 = 0; string row; for (int i = 0; i < n; ++i) { cin >> row; for (int j = 0; j < m; ++j) { if (row[j] == 'O') invariant1 += i + j; } } int invariant2 = 0; int pawns = 0; int moves = 0; int bound = (1 << m) - 1; int b1, b2; for (int i = 0; i < n; ++i) { cin >> row; for (int j = 0; j < m; ++j) { if (row[j] == 'O') invariant2 += i + j; } b1 = to_bin(m, row); pawns += PC(b1); moves += PC((b1 << 1) & ~b1 & bound); moves += PC((b1 >> 1) & ~b1 & bound); if (i) { moves += PC(b2 & ~b1 & bound); moves += PC(b1 & ~b2 & bound); } b2 = b1; } if ((invariant1 - invariant2) % 2) { cout << "0"; return 0; } vector<vector<int>> masks(pawns + 1); for (int b = 0; b < (1 << m); ++b) { if (PC(b) <= pawns) masks[PC(b)].push_back(b); } VVVL DP(n + 1, VVL(pawns + 1, VL(1 << m))); VVVL cnt(n + 1, VVL(pawns + 1, VL(1 << m))); cnt[0][0][0] = 1; for (int i = 1; i <= n; ++i) { for (int k = 0; k <= pawns; ++k) { for (int k1 = 0; k1 <= k; ++k1) { for (int b : masks[k1]) { for (int k2 = 0; k2 <= k - k1; ++k2) { for (int c : masks[k2]) { DP[i][k][b] += DP[i - 1][k - k1][c]; cnt[i][k][b] += cnt[i - 1][k - k1][c]; DP[i][k][b] += cnt[i - 1][k - k1][c] * (LL) PC((b << 1) & ~b & bound); DP[i][k][b] += cnt[i - 1][k - k1][c] * (LL) PC((b >> 1) & ~b & bound); if (i > 1) { DP[i][k][b] += cnt[i - 1][k - k1][c] * (LL) PC(c & ~b & bound); DP[i][k][b] += cnt[i - 1][k - k1][c] * (LL) PC(b & ~c & bound); } } } } } } } LL res = 0; for (int l = 0; l <= pawns; ++l) { for (int b : masks[l]) res += DP[n][pawns][b]; } res /= 2; cout << fixed << setprecision(15) << (long double) moves / (long double) res; }
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 115 116 117 118 119 120 121 122 123 124 125 | #include <iostream> #include <string> #include <algorithm> #include <vector> #include <iomanip> #define LL long long #define VL vector<LL> #define VVL vector<VL> #define VVVL vector<VVL> #define PC(b) __builtin_popcount(b) using namespace std; int to_bin(int n, string &s) { int res = 0; for (int i = 0; i < n; ++i) { res <<= 1; if (s[i] == 'O') ++res; } return res; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; int invariant1 = 0; string row; for (int i = 0; i < n; ++i) { cin >> row; for (int j = 0; j < m; ++j) { if (row[j] == 'O') invariant1 += i + j; } } int invariant2 = 0; int pawns = 0; int moves = 0; int bound = (1 << m) - 1; int b1, b2; for (int i = 0; i < n; ++i) { cin >> row; for (int j = 0; j < m; ++j) { if (row[j] == 'O') invariant2 += i + j; } b1 = to_bin(m, row); pawns += PC(b1); moves += PC((b1 << 1) & ~b1 & bound); moves += PC((b1 >> 1) & ~b1 & bound); if (i) { moves += PC(b2 & ~b1 & bound); moves += PC(b1 & ~b2 & bound); } b2 = b1; } if ((invariant1 - invariant2) % 2) { cout << "0"; return 0; } vector<vector<int>> masks(pawns + 1); for (int b = 0; b < (1 << m); ++b) { if (PC(b) <= pawns) masks[PC(b)].push_back(b); } VVVL DP(n + 1, VVL(pawns + 1, VL(1 << m))); VVVL cnt(n + 1, VVL(pawns + 1, VL(1 << m))); cnt[0][0][0] = 1; for (int i = 1; i <= n; ++i) { for (int k = 0; k <= pawns; ++k) { for (int k1 = 0; k1 <= k; ++k1) { for (int b : masks[k1]) { for (int k2 = 0; k2 <= k - k1; ++k2) { for (int c : masks[k2]) { DP[i][k][b] += DP[i - 1][k - k1][c]; cnt[i][k][b] += cnt[i - 1][k - k1][c]; DP[i][k][b] += cnt[i - 1][k - k1][c] * (LL) PC((b << 1) & ~b & bound); DP[i][k][b] += cnt[i - 1][k - k1][c] * (LL) PC((b >> 1) & ~b & bound); if (i > 1) { DP[i][k][b] += cnt[i - 1][k - k1][c] * (LL) PC(c & ~b & bound); DP[i][k][b] += cnt[i - 1][k - k1][c] * (LL) PC(b & ~c & bound); } } } } } } } LL res = 0; for (int l = 0; l <= pawns; ++l) { for (int b : masks[l]) res += DP[n][pawns][b]; } res /= 2; cout << fixed << setprecision(15) << (long double) moves / (long double) res; } |