개발 노트/알고리즘 문제
백준 9663 N-Queen
LeeInGyu
2025. 4. 8. 01:20
백준 9663 N-Queen
링크: 9663 N-Queen
접근 방법
- 퀸은 가로, 세로, 대각선 겹치지 않게 둬야 함
- 한 행마다 하나씩 두어야 함
- 따라서 각 행에 둬가면서 불가능한 경우만 제외하고 두기를 반복
소스 코드 1 (시간 초과)
소스 코드: 92762504 제출
N = int(input())
count = 0
visited_col = [False] * N
visited_cross_1 = [False] * (2*N+1)
visited_cross_2 = [False] * (2*N+1)
def backtracking(locate: tuple[int, int]) -> None:
global count
if locate[0] == N-1: # 체스판 끝(end of row)에 도착
count += 1
return
# 다음 행 중 가능한 것만 진행
for col in range(N):
cross1 = N + locate[0] - col
cross2 = locate[0] + 1 + col
if not (visited_col[col] or visited_cross_1[cross1] or visited_cross_2[cross2]):
visited_col[col] = True
visited_cross_1[cross1] = True
visited_cross_2[cross2] = True
backtracking((locate[0]+1, col))
visited_col[col] = False
visited_cross_1[cross1] = False
visited_cross_2[cross2] = False
return
for col in range(N):
# 현재 위치 방문 처리
visited_cross_1[N-1-col] = True
visited_cross_2[col] = True
visited_col[col] = True
backtracking((0, col)) # 현재 위치 퀸 두기
# 현재 위치 방문 해지
visited_cross_1[N-1-col] = False
visited_cross_2[col] = False
visited_col[col] = False
print(count)
- 반복되는 코드가 많아 줄여야 한다는 것을 깨달음
소스 코드 2
소스 코드: 92762758 제출
N = int(input())
count = 0
visited_col = [False] * N
visited_cross_1 = [False] * (2*N-1)
visited_cross_2 = [False] * (2*N-1)
def backtracking(row: int) -> None:
global count
if row == N: # 체스판 끝(end of row)에 도착
count += 1
return
# 다음 행 중 가능한 것만 진행
for col in range(N):
cross1 = N - 1 + row - col
cross2 = row + col
if not (visited_col[col] or visited_cross_1[cross1] or visited_cross_2[cross2]):
visited_col[col] = True
visited_cross_1[cross1] = True
visited_cross_2[cross2] = True
backtracking(row+1)
visited_col[col] = False
visited_cross_1[cross1] = False
visited_cross_2[cross2] = False
return
backtracking(0) # 현재 위치 퀸 두기
print(count)
- 리스트 재활용 코드에서 중복되는 부분을 지우고 다시 작성
결론
- 백트래킹이나 dfs에서 리스트를 재활용하는 아이디어는 정말 좋다 생각이 들어 항상 채택하고 있는데, 언제나 사용방법이 헷갈리는 것 같다.
- 그래도 약 4년 전 쯤 손도 대지 못했던 문제를 풀어 기쁘다!
끝.
728x90
반응형