반응형
문제
N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다.
N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N이 주어진다. (1 ≤ N < 15)
출력
첫째 줄에 퀸 N개를 서로 공격할 수 없게 놓는 경우의 수를 출력한다.
예제 입력8 |
예제 출력92 |
풀이
백트래킹으로 유명한 예제 중 하나라고 한다.
파이썬으로도 풀 순 있지만, 무거운 언어이다 보니 시간 초과가 발생한다.
동일한 코드를 PyPy3로 제출하면 정답으로 처리된다.
퀸은 기본적으로 수직, 수평, 대각선으로 공격이 가능하다.
우선 수직, 수평만 생각해봤을 때,
N x N 의 체스판에 N 개의 퀸을 두려면 무조건 가로, 세로 줄 마다 하나씩은 놓여야 한다.
따라서 첫 번째 가로줄부터 시작해서 차례대로 퀸을 놓아주고,
퀸을 놓았다면 다음 줄로 가서 퀸을 놓는 로직을 사용할 것이다.
여기서, 재귀가 필요함을 알 수 있다.
8 x 8 체스판을 예를 들자.
row = [[0]*8 for i in range(8)]
이렇게 8 x 8 의 2차원 배열을 만들어 풀 것이다.
알고리즘의 순서는 이렇다.
- 현재 줄의 퀸이 놓일 자리에 수직상에 다른 퀸이 있는지 판별한다.
- 없다면 대각선으로도 판별한다.
- 대각선에도 없다면 퀸을 놓고 다음 줄로 넘어간다.
- 마지막 줄이라면 모든 퀸이 놓였으므로 카운트하고 다시 퀸을 뺀 뒤, 이전 줄로 돌아가 순환한다.
아래는 정답 코드이다.
n = int(input())
row = [[0]*n for i in range(n)]
count = 0
def queen(a):
if a == n:
global count
count+=1
return
# 퀸이 모두 놓였으므로 카운트하고 종료
for i in range(n):
skip = 0
for j in range(n):
if row[j][i] == 1:
break
# 수직상의 퀸 검사
else:
for k in range(a):
if (row[k].index(1) == i + a-k) | (row[k].index(1) == i - (a-k)):
# 대각선상의 퀸 검사
skip = 1
break
if skip == 1:
continue
# 반복문 두 개를 한번에 건너뛸 수 없으므로
# 변수를 활용해준다.
row[a][i] = 1
queen(a+1)
row[a][i] = 0
queen(0)
print(count)
반응형
'알고리즘 연습 > 백트래킹' 카테고리의 다른 글
[🥈1 / 백준 14888 / 파이썬] 연산자 끼워넣기 (0) | 2021.06.13 |
---|---|
[🥇4 / 백준 2580 / 파이썬] 스도쿠 (0) | 2021.06.12 |
[🥈3 / 백준 15652 / 파이썬] N과 M (4) (0) | 2021.06.09 |
[🥈3 / 백준 15651 / 파이썬] N과 M (3) (0) | 2021.06.09 |
[🥈3 / 백준 15650 / 파이썬] N과 M (2) (0) | 2021.06.09 |