풀이 및 해설(주석)
import sys
# sys.stdin = open('칠공주.txt', 'r')
sys.setrecursionlimit(10**6)
# dfs와 bfs가 섞여서 사용됨
def solve(nums, S, Y):
global rst, visit
if Y > 3: return
# 중복 방지를 위해 7개의 글자의 좌표를 정렬해서 튜플로 묶어서 visit이란 set에 저장
if len(nums) == 7:
nums = tuple(sorted(nums))
if nums not in visit:
rst += 1
visit.add(nums)
return
return
# 여기서 부터가 bfs섞인 부분, nums에 넣어준 좌표들을 pop하면 안됨 그냥 읽으면 됨
for num in nums:
r, c = num[0], num[1]
for dr, dc in [[1, 0], [0, 1], [-1, 0], [0, -1]]:
nr, nc = r + dr, c + dc
if 0 <= nr < N and 0 <= nc < N:
# 방문 여부를 확인하기 위한 작업, 그냥 nums안에 있으면 방문했던 곳임
if (nr, nc) not in nums:
if students[nr][nc] == 'Y':
solve(nums+[(nr, nc)], S, Y+1)
else:
solve(nums+[(nr, nc)], S+1, Y)
students = [list(map(str, input())) for _ in range(5)]
N = 5
visit = set()
rst = 0
for i in range(N):
for j in range(N):
if students[i][j] == 'S':
solve([(i, j)], 1, 0)
else:
solve([(i, j)], 0, 1)
print(rst)
후기 및 해설
- 처음 문제를 보고, dfs로 풀면 되겠다 라고 판단 -> 실패
- 이유: dfs는 크로스로 방문이 안됨.
0 1 0 0
0 1 1 1
0 1 0 0
0 1 0 0
- 이런 식으로는 탐색이 안됨.
- bfs를 사용하는데, dfs처럼 재귀를 이용
- solve함수는 nums: list (좌표들을 튜플로 저장), S (S의 수), Y (Y의 수)를 매개변수로 받음
- 가지치기 적당히 넣어주고, nums의 수가 7개면 이다솜파가 될 수 있는 학생들을 찾은거임
- 이때, 중복 방지위해 [(0, 1), (0, 2)...] 형태로 저장된 nums를 visit이란 set에 넣어주기 위해
- 먼저 정렬하고, 튜플로 변경하고 visit에 저장
- 어려운 문제였음..
'백준' 카테고리의 다른 글
백준 14501 퇴사 (파이썬) (0) | 2022.10.08 |
---|---|
백준 7562 나이트의 이동 (파이썬) (1) | 2022.10.03 |
백준 1697 숨바꼭질 (파이썬) (0) | 2022.09.28 |
백준 1654 랜선 자르기 (이진 탐색) (파이썬) (0) | 2022.09.25 |
백준 2108 통계학 Counter 사용 (파이썬) (0) | 2022.09.25 |