Algorithm(BOJ, Python)/BFS&DFS
[백준_22352] 항체인식 python
kurooru
2022. 9. 13. 13:02
# n, m 입력
n, m = map(int, input().split())
# case_before 입력
case_before = [
list(map(int, input().split()))
for _ in range(n)
]
# case_after 입력
case_after = [
list(map(int, input().split()))
for _ in range(n)
]
# 함수들
# test_2()
def test_2():
# 색깔이 변한 횟수
cnt = 0
# 섹션의 대푯값들을 뽑기
for section in sections:
x, y = section[0]
if case_before[x][y] != case_after[x][y]:
cnt += 1
# 두 섹션 이상에서 색깔이 변했으면,
if cnt >= 2:
# 실패
return False
# 다 통과했으면 성공
return True
# test_1()
def test_1():
# sections 안의 각 구역들을 꺼내
for section in sections:
for i in range(len(section) - 1):
x, y = section[i]
nx, ny = section[i+1]
# 한번이라도 서로 숫자가 다르면
if case_after[x][y] != case_after[nx][ny]:
# 실패
return False
# 다 꺼냈는데 똑같으면 성공
return True
# in_range(x, y)
def in_range(x, y):
return 0 <= x < n and 0 <= y < m
# can_spread(x, y)
def can_spread(x, y):
# 범위 내에 있고, 방문한 적 없으면 가능
return in_range(x, y) and not visited[x][y]
# bfs()
def bfs():
global curr_section
while q:
x, y = q.popleft()
dxs, dys = [-1, 1, 0, 0], [0, 0, -1, 1]
for dx, dy in zip(dxs, dys):
nx, ny = x + dx, y + dy
# 퍼질 수 있으면
if can_spread(nx, ny) and case_before[x][y] == case_before[nx][ny]:
# 큐에 넣어주고
q.append((nx, ny))
# 방문 처리 해 주고
visited[nx][ny] = 1
# curr_section에 넣어주기
curr_section.append((nx, ny))
# find(x, y)
def find(x, y):
global curr_section
# 현재 연결된 좌표들을 관리해 줄 리스트
curr_section = []
# 큐에 넣어주고
q.append((x, y))
# 방문 처리 해 주고
visited[x][y] = 1
# 현재 좌표에도 넣어주고
curr_section.append((x, y))
# bfs 돌려주기
bfs()
# 전체 좌표 리스트에 넣어주기
sections.append(curr_section)
# 설계
# 큐 사용준비
from collections import deque
q = deque()
# 구역들의 좌표를 구분하여 기록해 둘 리스트
sections = []
# visited
visited = [
[0] * m
for _ in range(n)
]
# case_before을 돌면서,
for i in range(n):
for j in range(m):
# 방문하지 않은 칸을 만나면,
if not visited[i][j]:
# 이와 연결된 좌표들을 찾아,
# 한 구역으로 sections에 넣어주는 함수
find(i, j)
# test_1과 test_2를 통과하면,
if test_1() and test_2():
print('YES')
# 통과하지 못하면
else:
print('NO')