250x250
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 비관적락
- PS
- exclusive lock
- fetch
- 낙관적락
- CHECK OPTION
- 힙
- 다대다
- 스토어드 프로시저
- 지연로딩
- 동적sql
- 일대다
- 데코레이터
- 스프링 폼
- execute
- FetchType
- shared lock
- eager
- 유니크제약조건
- 이진탐색
- 연관관계
- 다대일
- 즉시로딩
- 백트래킹
- 연결리스트
- SQL프로그래밍
- dfs
- BOJ
- JPQL
- querydsl
Archives
- Today
- Total
흰 스타렉스에서 내가 내리지
[노트] 백트래킹 본문
728x90
# 백트래킹
- 현재 상태에서 다음 상태로 가는 모든 경우의 수를 찾아서, 이 경우가 답이 될 수 없으면 그 노드의 이전(부모)로 돌아간다.
- 구현을 하면 재귀 형태가 된다.
- 재귀 함수는 탈출 조건이 필요한데, 탈출 조건은 해를 만족하였을 때로 하면 된다.
# 백트래킹의 포맷
def backtrack(candidate):
# 만약 현재 후보군이 유효한 해라면 정답 처리하고 backtrack 함수를 종료
if find_solution(candidate):
output(candidate)
return
# 반복문을 돌면서 가능한 모든 후보군에 대해 탐색
for next_candidate in list_of_candidates:
# 유효한 후보군인 경우에만 탐색 진행
if is_valid(next_candidate):
# 이 후보군을 우선 추가하고,
place(next_candidate)
# 후보군을 추가한 상태에서 다음 후보군에 대해서 탐색 진행
backtrack(next_candidate)
# 해당 후보군에 대한 탐색을 종료한 이후에는 제거
remove(next_candidate)
# 순열 구하는 문제
n, m = map(int, input().split())
res = []
def f():
if len(res) == m:
print(*res)
return
for i in range(1, n+1):
if i not in res:
res.append(i)
f()
res.pop()
f()
# 스도쿠 문제
https://www.acmicpc.net/problem/2580
def check_row(x, a):
for i in range(9):
if a == mat[x][i]:
return False
return True
def check_col(x, a):
for i in range(9):
if a == mat[i][x]:
return False
return True
def check_box(x, y, a):
x, y = x//3*3, y//3*3
for i in range(3):
for j in range(3):
if a == mat[x+i][y+j]:
return False
return True
def f(num):
if num == len(blank):
for m in mat:
print(*m)
exit(0)
for i in range(1, 10):
x, y = blank[num]
if check_row(x, i) and check_col(y, i) and check_box(x, y, i):
mat[x][y] = i
f(num+1)
mat[x][y] = 0
mat = []
blank = []
for _ in range(9):
line = list(map(int, input().split()))
for i in range(9):
if not line[i]:
blank.append((_, i))
mat.append(line)
f(0)
- 처음 데이터를 입력받을 때 빈칸의 좌표를 따로 blank 배열에 저장한다.
- 백트래킹 재귀함수 실행
- 탈출 조건 : 빈칸을 전부 채웠을 때. 출력 후 바로 프로그램 종료
- 1~9 까지의 모든 수에 대하여, 반복문을 수행함
- 빈칸의 좌표를 꺼내고, 가로/세로/블럭 전부 체크 후 들어갈 수 있으면 빈칸을 채우고, 다음 블럭으로 감
# N-Queen 문제
n = int(input())
board = [[False]*n for _ in range(n)]
dx = [-1, -1, 0, 1, 1, 1, 0, -1]
dy = [0, 1, 1, 1, 0, -1, -1, -1]
res = 0
def f(row):
global res
if row == n:
res += 1
return
for col in range(n):
if is_safe(row, col):
board[row][col] = True
f(row+1)
board[row][col] = False
def is_safe(r, c):
for i in range(8):
nr, nc = r, c
while True:
nr, nc = nr+dx[i], nc +dy[i]
if not (0<=nr<n and 0<=nc<n): break
if board[nr][nc]:
return False
return True
f(0)
print(res)
'Problem Solving' 카테고리의 다른 글
[Time Complexity 분석] BOJ 9935 문자열 폭발 (0) | 2024.01.20 |
---|---|
[노트] 최장 부분수열 (LIS) (1) | 2024.01.17 |
[노트]deque에서, 원소를 계속 pop하면서 순회할 경우 (0) | 2024.01.16 |
(가설..) BFS - deque 일 경우와 heapq 일 경우 (1) | 2024.01.06 |
최단 경로 찾기 (1) | 2023.12.28 |