import numpy as np import itertools VALUES = { (4, 4): [8736, 24024, 48048, 72072, 82368, ], (4, 5): [25296, 94860, 265608, 575484, 986544, ], (4, 6): [58520, 277970, 1000692, 2835294, 6480672, ], (4, 7): [117000, 672750, 2960100, 10360350, 29601000, ], (4, 8): [211120, 1425060, 7410312, 30876300, 105861600, ], (5, 4): [25296, 94860, 265608, 575484, 986544, ], (5, 5): [70840, 354200, 1345960, 4037880, 9806280, ], (5, 6): [160524, 1003275, 4815720, 18460260, 58017960, ], (5, 7): [316448, 2373360, 13765488, 64238944, 247778784, ], (5, 8): [565212, 4945605, 33630114, 184965627, 845557152, ], (6, 4): [58520, 277970, 1000692, 2835294, 6480672, ], (6, 5): [160524, 1003275, 4815720, 18460260, 58017960, ], (6, 6): [359040, 2782560, 16695360, 80694240, 322776960, ], (6, 7): [701480, 6488690, 46718568, 272524980, 1323692760, ], (6, 8): [1244760, 13381170, 112401828, 768079158, 4389023760, ], (7, 4): [117000, 672750, 2960100, 10360350, 29601000, ], (7, 5): [316448, 2373360, 13765488, 64238944, 247778784, ], (7, 6): [701480, 6488690, 46718568, 272524980, 1323692760, ], (7, 7): [1362060, 14982660, 128850876, 901956132, 5282885916, ], (7, 8): [2405988, 30676347, 306763470, 2505235005, 17178754320, ], (8, 4): [211120, 1425060, 7410312, 30876300, 105861600, ], (8, 5): [565212, 4945605, 33630114, 184965627, 845557152, ], (8, 6): [1244760, 13381170, 112401828, 768079158, 4389023760, ], (8, 7): [2405988, 30676347, 306763470, 2505235005, 17178754320, ], (8, 8): [4235840, 62478640, 724752224, 6885146128, 55081169024, ] } def read_board(n, m): board = np.zeros((n, m)) for i in range(n): line = input() for j, l in enumerate(line): if l == 'O': board[i, j] = 1 return board def calculate(pawns, end_position, n, m, parity): sum = 0 # print(parity) sum_of_position = 0 position_coutner = 0 test_sum = 0 for pawn in end_position: row, col = pawn//m, pawn%m test_sum += row test_sum += col if test_sum % 2 != parity: return 0 for pawn in end_position: row, col = pawn//m, pawn%m if row + 1 < n and (row+1)*m + col not in end_position: sum_of_position += 1 if row > 0 and (row-1)*m + col not in end_position: sum_of_position += 1 if col > 0 and row*m + col - 1 not in end_position: sum_of_position += 1 if col + 1 < m and row*m + col + 1 not in end_position: sum_of_position += 1 if (n, m) in VALUES and pawns > 3: return sum_of_position/VALUES[(n, m)][pawns-4] for i, position in enumerate((itertools.combinations(list(range(n*m)), pawns))): test_sum = 0 for pawn in position: row, col = pawn//m, pawn%m test_sum += row test_sum += col if test_sum % 2 != parity: continue for pawn in position: row, col = pawn//m, pawn%m if row + 1 < n and (row+1)*m + col not in position: sum += 1 if row > 0 and (row-1)*m + col not in position: sum += 1 if col > 0 and row*m + col - 1 not in position: sum += 1 if col + 1 < m and row*m + col + 1 not in position: sum += 1 # if i%100_000_000 == 0: # print(i) return sum_of_position/sum def positions_to_values(l, n, m): result = [] for elem in l: result.append(elem[0]*m + elem[1]) return tuple(sorted(result)) def main(): n, m = (int(x) for x in input().split()) board = read_board(n, m) input() end_position = read_board(n, m) end_position = positions_to_values(np.array(np.where(end_position == 1)).T, n, m) starting_positions = np.array(np.where(board == 1)).T probabilities = { positions_to_values(starting_positions, n, m): 1 } # print(probabilities) parity = np.sum(np.where(board == 1))%2 # print(len(simulate(probabilities, 16_000, n, m, end_position))) print(f"{calculate(len(np.where(board == 1)[0]), end_position, n, m, parity):.15f}") if __name__ == '__main__': main() # print(calculate(6, 0, 8, 8, 1))
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 | import numpy as np import itertools VALUES = { (4, 4): [8736, 24024, 48048, 72072, 82368, ], (4, 5): [25296, 94860, 265608, 575484, 986544, ], (4, 6): [58520, 277970, 1000692, 2835294, 6480672, ], (4, 7): [117000, 672750, 2960100, 10360350, 29601000, ], (4, 8): [211120, 1425060, 7410312, 30876300, 105861600, ], (5, 4): [25296, 94860, 265608, 575484, 986544, ], (5, 5): [70840, 354200, 1345960, 4037880, 9806280, ], (5, 6): [160524, 1003275, 4815720, 18460260, 58017960, ], (5, 7): [316448, 2373360, 13765488, 64238944, 247778784, ], (5, 8): [565212, 4945605, 33630114, 184965627, 845557152, ], (6, 4): [58520, 277970, 1000692, 2835294, 6480672, ], (6, 5): [160524, 1003275, 4815720, 18460260, 58017960, ], (6, 6): [359040, 2782560, 16695360, 80694240, 322776960, ], (6, 7): [701480, 6488690, 46718568, 272524980, 1323692760, ], (6, 8): [1244760, 13381170, 112401828, 768079158, 4389023760, ], (7, 4): [117000, 672750, 2960100, 10360350, 29601000, ], (7, 5): [316448, 2373360, 13765488, 64238944, 247778784, ], (7, 6): [701480, 6488690, 46718568, 272524980, 1323692760, ], (7, 7): [1362060, 14982660, 128850876, 901956132, 5282885916, ], (7, 8): [2405988, 30676347, 306763470, 2505235005, 17178754320, ], (8, 4): [211120, 1425060, 7410312, 30876300, 105861600, ], (8, 5): [565212, 4945605, 33630114, 184965627, 845557152, ], (8, 6): [1244760, 13381170, 112401828, 768079158, 4389023760, ], (8, 7): [2405988, 30676347, 306763470, 2505235005, 17178754320, ], (8, 8): [4235840, 62478640, 724752224, 6885146128, 55081169024, ] } def read_board(n, m): board = np.zeros((n, m)) for i in range(n): line = input() for j, l in enumerate(line): if l == 'O': board[i, j] = 1 return board def calculate(pawns, end_position, n, m, parity): sum = 0 # print(parity) sum_of_position = 0 position_coutner = 0 test_sum = 0 for pawn in end_position: row, col = pawn//m, pawn%m test_sum += row test_sum += col if test_sum % 2 != parity: return 0 for pawn in end_position: row, col = pawn//m, pawn%m if row + 1 < n and (row+1)*m + col not in end_position: sum_of_position += 1 if row > 0 and (row-1)*m + col not in end_position: sum_of_position += 1 if col > 0 and row*m + col - 1 not in end_position: sum_of_position += 1 if col + 1 < m and row*m + col + 1 not in end_position: sum_of_position += 1 if (n, m) in VALUES and pawns > 3: return sum_of_position/VALUES[(n, m)][pawns-4] for i, position in enumerate((itertools.combinations(list(range(n*m)), pawns))): test_sum = 0 for pawn in position: row, col = pawn//m, pawn%m test_sum += row test_sum += col if test_sum % 2 != parity: continue for pawn in position: row, col = pawn//m, pawn%m if row + 1 < n and (row+1)*m + col not in position: sum += 1 if row > 0 and (row-1)*m + col not in position: sum += 1 if col > 0 and row*m + col - 1 not in position: sum += 1 if col + 1 < m and row*m + col + 1 not in position: sum += 1 # if i%100_000_000 == 0: # print(i) return sum_of_position/sum def positions_to_values(l, n, m): result = [] for elem in l: result.append(elem[0]*m + elem[1]) return tuple(sorted(result)) def main(): n, m = (int(x) for x in input().split()) board = read_board(n, m) input() end_position = read_board(n, m) end_position = positions_to_values(np.array(np.where(end_position == 1)).T, n, m) starting_positions = np.array(np.where(board == 1)).T probabilities = { positions_to_values(starting_positions, n, m): 1 } # print(probabilities) parity = np.sum(np.where(board == 1))%2 # print(len(simulate(probabilities, 16_000, n, m, end_position))) print(f"{calculate(len(np.where(board == 1)[0]), end_position, n, m, parity):.15f}") if __name__ == '__main__': main() # print(calculate(6, 0, 8, 8, 1)) |