結果
| 問題 |
No.640 76本のトロンボーン
|
| コンテスト | |
| ユーザー |
gew1fw
|
| 提出日時 | 2025-06-12 18:58:09 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,185 bytes |
| コンパイル時間 | 345 ms |
| コンパイル使用メモリ | 81,856 KB |
| 実行使用メモリ | 71,144 KB |
| 最終ジャッジ日時 | 2025-06-12 18:58:11 |
| 合計ジャッジ時間 | 1,950 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 8 WA * 7 |
ソースコード
from collections import deque
def main():
N = int(input())
grid = [input().strip() for _ in range(N)]
# For each column, find all possible vertical trombone ranges (1-based)
vert_available = [] # vert_available[c] is list of (start, end) for column c (0-based)
for c in range(N):
ranges = []
max_i = N - (N - 1)
for i in range(max_i):
start_row = i + 1 # 1-based
end_row = start_row + (N - 1) - 1
valid = True
for row in range(start_row - 1, end_row): # convert to 0-based
if row >= N or grid[row][c] == '#':
valid = False
break
if valid:
ranges.append((start_row, end_row))
vert_available.append(ranges)
C = [c for c in range(N) if vert_available[c]]
# For each row, find all possible horizontal trombone ranges (1-based)
horiz_available = [] # horiz_available[r] is list of (start, end) for row r (0-based)
for r in range(N):
ranges = []
max_j = N - (N - 1)
for j in range(max_j):
start_col = j + 1 # 1-based
end_col = start_col + (N - 1) - 1
valid = True
for col in range(start_col - 1, end_col): # convert to 0-based
if col >= N or grid[r][col] == '#':
valid = False
break
if valid:
ranges.append((start_col, end_col))
horiz_available.append(ranges)
R = [r for r in range(N) if horiz_available[r]]
# Build edges between columns in C and rows in R if they intersect
edges = []
for c in C:
for r in R:
# Check if row r+1 (1-based) is in any vertical range of column c
current_r_1based = r + 1
in_vert = False
for (start, end) in vert_available[c]:
if start <= current_r_1based <= end:
in_vert = True
break
if not in_vert:
continue
# Check if column c+1 (1-based) is in any horizontal range of row r
current_c_1based = c + 1
in_horiz = False
for (start, end) in horiz_available[r]:
if start <= current_c_1based <= end:
in_horiz = True
break
if in_horiz:
edges.append((c, r))
# Build adjacency list for bipartite graph
graph = {c: [] for c in C}
for c, r in edges:
graph[c].append(r)
# Hopcroft-Karp algorithm implementation
def hopcroft_karp():
pair_U = {u: None for u in C}
pair_V = {v: None for v in R}
dist = {}
def bfs():
queue = deque()
for u in C:
if pair_U[u] is None:
dist[u] = 0
queue.append(u)
else:
dist[u] = float('inf')
dist[None] = float('inf')
while queue:
u = queue.popleft()
if u is not None:
for v in graph[u]:
if dist.get(pair_V.get(v, None), float('inf')) == float('inf'):
dist[pair_V.get(v, None)] = dist[u] + 1
queue.append(pair_V.get(v, None))
return dist.get(None, float('inf')) != float('inf')
def dfs(u):
if u is not None:
for v in graph[u]:
if dist.get(pair_V.get(v, None), float('inf')) == dist[u] + 1:
if dfs(pair_V.get(v, None)):
pair_U[u] = v
pair_V[v] = u
return True
dist[u] = float('inf')
return False
return True
result = 0
while bfs():
for u in C:
if pair_U[u] is None:
if dfs(u):
result += 1
return result
max_matching = hopcroft_karp()
X = len(C) + len(R) - max_matching
print(X)
if __name__ == "__main__":
main()
gew1fw