#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned int ui; typedef pair<int, int> pii; typedef vector<int> vi; typedef vector<long long> vll; const ll LINF = 1e18; const int INF = 1e9; const int N = 8; char board[N][N]; char target_board[N][N]; bool is_valid(int x, int n) { return x >= 0 && x < n; } int count_moves_for_square(int x, int y, int n, int m) { static const array<pii, 4> offsets = {{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}}; int cnt = 0; for (size_t i = 0; i < offsets.size(); ++i) { int new_x = x + offsets[i].first; int new_y = y + offsets[i].second; if (is_valid(new_x, n) && is_valid(new_y, m)) { ++cnt; } } return cnt; } ll count_all_transitions(int n, int m, int n_pawns) { ll binom_coeff[n * m + 1][n_pawns + 1]; ll n_moves[n_pawns + 1]; memset(n_moves, 0, sizeof(n_moves)); memset(binom_coeff, 0, sizeof(binom_coeff)); binom_coeff[0][0] = 1; for (int i = 1; i <= n * m; ++i) { binom_coeff[i][0] = 1; for (int k = 1; k <= min(n_pawns, i); ++k) { binom_coeff[i][k] = binom_coeff[i - 1][k] + binom_coeff[i - 1][k - 1]; } } for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { int idx = i * m + j; int cnt_moves = count_moves_for_square(i, j, n, m); for (int k = n_pawns; k >= 1; --k) { ll new_states = binom_coeff[idx][k - 1]; n_moves[k] += cnt_moves * new_states + n_moves[k - 1]; if (k <= 1) { // cerr << i << ' ' << j << ' ' << k << ' ' << n_moves[k] << '\n'; continue; } // Remove moves for occupied squares if (j >= 1) { n_moves[k] -= 2 * binom_coeff[idx - 1][k - 2]; } if (i >= 1) { n_moves[k] -= 2 * binom_coeff[idx - 1][k - 2]; } // cerr << i << ' ' << j << ' ' << k << ' ' << n_moves[k] << '\n'; } } } return n_moves[n_pawns]; } ll count_moves(char board[N][N], int n, int m) { static const array<pii, 4> offsets = {{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}}; int cnt = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (board[i][j] != 'O') { continue; } for (const pii &offset : offsets) { int new_x = i + offset.first; int new_y = j + offset.second; if (is_valid(new_x, n) && is_valid(new_y, m) && board[new_x][new_y] != 'O') { ++cnt; } } } } return cnt; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; int n_pawns = 0; int start_parity = 0, target_parity = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> board[i][j]; if (board[i][j] == 'O') { ++n_pawns; start_parity += i + j; start_parity %= 2; } } } for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> target_board[i][j]; if (target_board[i][j] == 'O') { target_parity += i + j; target_parity %= 2; } } } // cerr << "Parity: " << start_parity << ' ' << target_parity << endl; // check if parity of start and target are equal if (start_parity != target_parity) { cout << 0 << endl; return 0; } ll all_transitions = count_all_transitions(n, m, n_pawns); // cerr << "All transitions: " << all_transitions << endl; int moves_from_target = count_moves(target_board, n, m); // cerr << "Moves from target: " << moves_from_target << endl; cout << fixed << setprecision(15) << static_cast<double>(2 * moves_from_target) / all_transitions << 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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | #include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned int ui; typedef pair<int, int> pii; typedef vector<int> vi; typedef vector<long long> vll; const ll LINF = 1e18; const int INF = 1e9; const int N = 8; char board[N][N]; char target_board[N][N]; bool is_valid(int x, int n) { return x >= 0 && x < n; } int count_moves_for_square(int x, int y, int n, int m) { static const array<pii, 4> offsets = {{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}}; int cnt = 0; for (size_t i = 0; i < offsets.size(); ++i) { int new_x = x + offsets[i].first; int new_y = y + offsets[i].second; if (is_valid(new_x, n) && is_valid(new_y, m)) { ++cnt; } } return cnt; } ll count_all_transitions(int n, int m, int n_pawns) { ll binom_coeff[n * m + 1][n_pawns + 1]; ll n_moves[n_pawns + 1]; memset(n_moves, 0, sizeof(n_moves)); memset(binom_coeff, 0, sizeof(binom_coeff)); binom_coeff[0][0] = 1; for (int i = 1; i <= n * m; ++i) { binom_coeff[i][0] = 1; for (int k = 1; k <= min(n_pawns, i); ++k) { binom_coeff[i][k] = binom_coeff[i - 1][k] + binom_coeff[i - 1][k - 1]; } } for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { int idx = i * m + j; int cnt_moves = count_moves_for_square(i, j, n, m); for (int k = n_pawns; k >= 1; --k) { ll new_states = binom_coeff[idx][k - 1]; n_moves[k] += cnt_moves * new_states + n_moves[k - 1]; if (k <= 1) { // cerr << i << ' ' << j << ' ' << k << ' ' << n_moves[k] << '\n'; continue; } // Remove moves for occupied squares if (j >= 1) { n_moves[k] -= 2 * binom_coeff[idx - 1][k - 2]; } if (i >= 1) { n_moves[k] -= 2 * binom_coeff[idx - 1][k - 2]; } // cerr << i << ' ' << j << ' ' << k << ' ' << n_moves[k] << '\n'; } } } return n_moves[n_pawns]; } ll count_moves(char board[N][N], int n, int m) { static const array<pii, 4> offsets = {{{1, 0}, {0, 1}, {-1, 0}, {0, -1}}}; int cnt = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (board[i][j] != 'O') { continue; } for (const pii &offset : offsets) { int new_x = i + offset.first; int new_y = j + offset.second; if (is_valid(new_x, n) && is_valid(new_y, m) && board[new_x][new_y] != 'O') { ++cnt; } } } } return cnt; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; int n_pawns = 0; int start_parity = 0, target_parity = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> board[i][j]; if (board[i][j] == 'O') { ++n_pawns; start_parity += i + j; start_parity %= 2; } } } for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { cin >> target_board[i][j]; if (target_board[i][j] == 'O') { target_parity += i + j; target_parity %= 2; } } } // cerr << "Parity: " << start_parity << ' ' << target_parity << endl; // check if parity of start and target are equal if (start_parity != target_parity) { cout << 0 << endl; return 0; } ll all_transitions = count_all_transitions(n, m, n_pawns); // cerr << "All transitions: " << all_transitions << endl; int moves_from_target = count_moves(target_board, n, m); // cerr << "Moves from target: " << moves_from_target << endl; cout << fixed << setprecision(15) << static_cast<double>(2 * moves_from_target) / all_transitions << endl; return 0; } |