結果
| 問題 |
No.348 カゴメカゴメ
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 2025-04-16 16:30:42 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,980 bytes |
| コンパイル時間 | 612 ms |
| コンパイル使用メモリ | 82,108 KB |
| 実行使用メモリ | 122,344 KB |
| 最終ジャッジ日時 | 2025-04-16 16:32:27 |
| 合計ジャッジ時間 | 5,502 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 2 TLE * 1 -- * 50 |
ソースコード
import sys
from collections import defaultdict
sys.setrecursionlimit(1 << 25)
def main():
N, M = map(int, sys.stdin.readline().split())
grid = [sys.stdin.readline().strip() for _ in range(N)]
# Step 1: Extract cycles using BFS to trace the perimeter
visited = [[False]*M for _ in range(N)]
cycles = []
for i in range(N):
for j in range(M):
if grid[i][j] == 'x' and not visited[i][j]:
start = (i, j)
current = start
prev = None
cycle = []
while True:
cycle.append(current)
visited[current[0]][current[1]] = True
next_cells = []
for dx in (-1, 0, 1):
for dy in (-1, 0, 1):
if dx == 0 and dy == 0:
continue
nx = current[0] + dx
ny = current[1] + dy
if 0 <= nx < N and 0 <= ny < M and grid[nx][ny] == 'x' and (nx, ny) != prev:
next_cells.append((nx, ny))
if not next_cells:
break
if len(next_cells) == 1:
next_cell = next_cells[0]
else:
next_cell = next_cells[0]
prev = current
current = next_cell
if current == start:
break
cycles.append((cycle, len(cycle)))
# Step 2: Build parent-child relationships
K = len(cycles)
parent = [-1] * K
def is_inside(point, cycle_points):
x, y = point
crossings = 0
n = len(cycle_points)
for i in range(n):
(x1, y1) = cycle_points[i]
(x2, y2) = cycle_points[(i + 1) % n]
if (y1 < y and y2 >= y) or (y2 < y and y1 >= y):
x_intersect = (y - y1) * (x2 - x1) / (y2 - y1 + 1e-9) + x1
if x <= x_intersect:
crossings += 1
return crossings % 2 == 1
for i in range(K):
(cycle_i, size_i) = cycles[i]
x, y = cycle_i[0]
candidate_parents = []
for j in range(K):
if i == j:
continue
(cycle_j, size_j) = cycles[j]
if is_inside((x, y), cycle_j):
candidate_parents.append(j)
# Find the deepest parent (the one with the most nested)
max_depth = -1
selected_parent = -1
for j in candidate_parents:
current_depth = 0
current = j
while parent[current] != -1:
current = parent[current]
current_depth += 1
if current_depth > max_depth:
max_depth = current_depth
selected_parent = j
if candidate_parents:
parent[i] = selected_parent
# Step 3: Build tree and perform DP
children = defaultdict(list)
for i in range(K):
if parent[i] != -1:
children[parent[i]].append(i)
else:
children[-1].append(i)
memo = {}
def dp(u, can_use):
if (u, can_use) in memo:
return memo[(u, can_use)]
res = 0
if can_use:
use_val = cycles[u][1]
for v in children[u]:
use_val += dp(v, False)
not_use_val = 0
for v in children[u]:
not_use_val += dp(v, True)
res = max(use_val, not_use_val)
else:
not_use_val = 0
for v in children[u]:
not_use_val += dp(v, True)
res = not_use_val
memo[(u, can_use)] = res
return res
total = 0
for root in children[-1]:
total += dp(root, True)
print(total)
if __name__ == '__main__':
main()
lam6er