n-queen 구현
백트레킹으로 누구나 한번쯤 들어봤을 문제.
간단하게 풀릴 것이라 예상하고 구현해봤는데 생각대로 잘 안된다.
첫 구현.
def way_on_queen(i, j, q):
visited(i, j, q)
dx = 1
while i + dx < N:
ni = i+dx
visited(ni, j+dx, q)
visited(ni, j-dx, q)
visited(ni, j, q)
dx += 1
def visited(i, j, q):
if 0 <= j < N and grid[i][j]:
grid[i][j] = False
q.append((i, j))
def bt(i, cnt):
global result
if cnt == N:
result += 1
return
for j in range(N):
if grid[i][j]:
q = []
way_on_queen(i, j, q)
bt(i+1, cnt+1)
for r, c in q:
grid[r][c] = True
N = int(input())
result = 0
grid = [[True] * N for _ in range(N)]
bt(0, 0)
print(result)
더 이상 개선할 부분이 없다고 생각했다.
queen을 놓으면 2차원 배열에 현재 행부터 끝까지 대각선, 열을 방문처리하는 것과
방문처리를 하면 백트래킹을 위해 q에 방문한 위치를 기억하도록 구현했다.
하지만 끝까지 시간초과에서 벗어날 수 없었다.
n = int(input())
check_row = [0 for i in range(n)]
check_leftcross = [0 for i in range(n*2)]
check_rightcross = [0 for i in range(n*2)]
ret = 0
def backtracking(cur):
if cur==n:
global ret
ret += 1
return 0
for i in range(n):
if check_row[i] or check_leftcross[n+cur-i] or check_rightcross[cur+i]:
continue
else:
check_row[i] = 1
check_leftcross[n+cur-i] = 1
check_rightcross[cur+i] = 1
backtracking(cur+1)
check_row[i] = 0
check_leftcross[n+cur-i] = 0
check_rightcross[cur+i] = 0
for i in range(n//2):
check_row[i] = 1
check_leftcross[n-i] = 1
check_rightcross[i] = 1
backtracking(1)
check_row[i] = 0
check_leftcross[n-i] = 0
check_rightcross[i] = 0
ret = ret*2
if n%2: #홀수일경우
i=n//2
check_row[i] = 1
check_leftcross[n-i] = 1
check_rightcross[i] = 1
backtracking(1)
check_row[i] = 0
check_leftcross[n-i] = 0
check_rightcross[i] = 0
print(ret)
우수한 코드를 풀이하면
check_leftcross의 2n개로 선언함으로써 대각선도 행과 열처럼 하나의 숫자로 표현할 수 있다는 성질을 이용한 것이다.
예를 들어 행이 4줄인 정사각형 모양이라면 총 7줄로 표현할 수 있다.
결과적으로 모든 행과 열, 대각선을 하나의 숫자로 표현할 수 있어서
2차원 배열이 아닌 1차원 배열로 표현하고 순회하지 않도록 구현할 수 있다.
참고
<built-in method builtins.input>
프로파일링 하다가 "input이 이렇게 오래걸린다고?" 하면서
나처럼 버그성 로그라고 생각한 사람이 있을까봐 적는다.
해당 함수의 시간은 입력을 받으려고 대기하는 순간부터의 시간을 의미한다.
'알고리즘' 카테고리의 다른 글
이진분류, 하노이 탑 (0) | 2024.01.08 |
---|---|
무방향 그래프와 서로소 집합 (0) | 2023.12.10 |
11.28 알고리즘 문제풀이 (1) | 2023.11.28 |
11.27 알고리즘 문제풀이 (0) | 2023.11.27 |
11.23 알고리즘 문제풀이 (0) | 2023.11.23 |