puzzle_rook.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. '''
  2. https://www.codingame.com/ide/18267536aa85810c92273263bca743a4f379f708
  3. @author: olinox14, 2019
  4. '''
  5. import sys
  6. def log(*msg):
  7. print(*msg, file=sys.stderr)
  8. rows = [list(input()) for _ in range(int(input()))]
  9. cols = [[r[i] for r in rows] for i in range(len(rows))]
  10. # for y, r in enumerate(rows):
  11. # log("".join(r))
  12. class XInterval():
  13. def __init__(self, y, xstart, xend=-1):
  14. self.y = y
  15. self.xstart = xstart
  16. self.xend = xend
  17. self.cells = []
  18. def __repr__(self):
  19. return f"<XI({self.xstart}, {self.y})-({self.xend}, {self.y})>"
  20. def __len__(self):
  21. return self.xend - self.xstart
  22. def update(self):
  23. self.cells = [(x, self.y) for x in range(self.xstart, self.xend)]
  24. class YInterval():
  25. def __init__(self, x, ystart, yend=-1):
  26. self.x = x
  27. self.ystart = ystart
  28. self.yend = yend
  29. self.cells = []
  30. def __repr__(self):
  31. return f"<YI({self.x}, {self.ystart})-({self.x}, {self.yend})>"
  32. def __len__(self):
  33. return self.yend - self.ystart
  34. def update(self):
  35. self.cells = [(self.x, y) for y in range(self.ystart, self.yend)]
  36. xintervals = []
  37. for y, row in enumerate(rows):
  38. current = XInterval(y, 0)
  39. for x, c in enumerate(row):
  40. if c == "X":
  41. if x > current.xstart:
  42. current.xend = x
  43. current.update()
  44. xintervals.append(current)
  45. current = XInterval(y, x + 1)
  46. if current.xstart < len(row):
  47. current.xend = len(row)
  48. current.update()
  49. xintervals.append(current)
  50. yintervals = []
  51. for x, col in enumerate(cols):
  52. current = YInterval(x, 0)
  53. for y, c in enumerate(col):
  54. if c == "X":
  55. if y > current.ystart:
  56. current.yend = y
  57. current.update()
  58. yintervals.append(current)
  59. current = YInterval(x, y + 1)
  60. if current.ystart < len(col):
  61. current.yend = len(col)
  62. current.update()
  63. yintervals.append(current)
  64. graph = [[any(c in yi.cells for c in xi.cells) for xi in xintervals] for yi in yintervals]
  65. def bpm(graph, u, matchR, seen):
  66. for v in range(len(xintervals)):
  67. if graph[u][v] and seen[v] == False:
  68. seen[v] = True
  69. if matchR[v] == -1 or bpm(graph, matchR[v], matchR, seen):
  70. matchR[v] = u
  71. return True
  72. return False
  73. def count_rooks(graph):
  74. matchR = [-1 for _ in xintervals]
  75. result = 0
  76. for i in range(len(yintervals)):
  77. seen = [False for _ in xintervals]
  78. if bpm(graph, i, matchR, seen):
  79. result += 1
  80. return result
  81. print(count_rooks(graph))