def binomial(n, k):
if n<0 or k<0 or k>n:
return 0
res = 1
for i in range(1, k+1):
res *= (n-i+1)
res //= i
return res
class Epsilon_maker:
@staticmethod
def string_to_positioning(board, n, m):
res = []
for i in range(n):
for j in range(m):
if board[i][j] != '.':
res.append((i, j))
return res
@staticmethod
def check_parity(pawn_positions):
res = 0
for pawn in pawn_positions:
res += pawn[0] + pawn[1]
return res%2
def correct(self, x, y, pawn_positions):
if x >= 0 and x < n and y >= 0 and y < m and (x, y) not in pawn_positions:
return True
return False
def get_neighbours(self, pawn_positions):
moves = ((1, 0), (-1, 0), (0, 1), (0, -1))
res = 0
for current_pawn in pawn_positions:
for move in moves:
new_pawn = (current_pawn[0]+move[0], current_pawn[1]+move[1])
if self.correct(new_pawn[0], new_pawn[1], pawn_positions):
res += 1
return res
def __init__(self, n, m, pawns):
self.n, self.m = n, m
all_elements = [(x//m, x%m) for x in range(0, n*m)]
self.all_free_states = 0
for x in all_elements:
self.all_free_states += self.get_free_states({x}) * (binomial(n*m-1, pawns-1) - binomial(n*m-2, pawns-2))
self.all_free_states //= 2
def get_free_states(self, positional):
return self.get_neighbours(positional)
n, m = [int(x) for x in input().split(' ')]
start = []
end = []
for i in range(n):
start.append(input())
input()
for i in range(n):
end.append(input())
proper_start = Epsilon_maker.string_to_positioning(start, n, m)
proper_end = Epsilon_maker.string_to_positioning(end, n, m)
pawns = len(proper_start)
pairwise = Epsilon_maker.check_parity(proper_start)
pairwise_end = Epsilon_maker.check_parity(proper_end)
if pairwise != pairwise_end:
print(0)
else:
epsilon = Epsilon_maker(n, m, pawns)
odds = 1/epsilon.all_free_states
free_states_end = epsilon.get_free_states(proper_end)
print(f'{free_states_end*odds:.15f}')
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 | def binomial(n, k): if n<0 or k<0 or k>n: return 0 res = 1 for i in range(1, k+1): res *= (n-i+1) res //= i return res class Epsilon_maker: @staticmethod def string_to_positioning(board, n, m): res = [] for i in range(n): for j in range(m): if board[i][j] != '.': res.append((i, j)) return res @staticmethod def check_parity(pawn_positions): res = 0 for pawn in pawn_positions: res += pawn[0] + pawn[1] return res%2 def correct(self, x, y, pawn_positions): if x >= 0 and x < n and y >= 0 and y < m and (x, y) not in pawn_positions: return True return False def get_neighbours(self, pawn_positions): moves = ((1, 0), (-1, 0), (0, 1), (0, -1)) res = 0 for current_pawn in pawn_positions: for move in moves: new_pawn = (current_pawn[0]+move[0], current_pawn[1]+move[1]) if self.correct(new_pawn[0], new_pawn[1], pawn_positions): res += 1 return res def __init__(self, n, m, pawns): self.n, self.m = n, m all_elements = [(x//m, x%m) for x in range(0, n*m)] self.all_free_states = 0 for x in all_elements: self.all_free_states += self.get_free_states({x}) * (binomial(n*m-1, pawns-1) - binomial(n*m-2, pawns-2)) self.all_free_states //= 2 def get_free_states(self, positional): return self.get_neighbours(positional) n, m = [int(x) for x in input().split(' ')] start = [] end = [] for i in range(n): start.append(input()) input() for i in range(n): end.append(input()) proper_start = Epsilon_maker.string_to_positioning(start, n, m) proper_end = Epsilon_maker.string_to_positioning(end, n, m) pawns = len(proper_start) pairwise = Epsilon_maker.check_parity(proper_start) pairwise_end = Epsilon_maker.check_parity(proper_end) if pairwise != pairwise_end: print(0) else: epsilon = Epsilon_maker(n, m, pawns) odds = 1/epsilon.all_free_states free_states_end = epsilon.get_free_states(proper_end) print(f'{free_states_end*odds:.15f}') |
English