일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 1002
- 그리디 알고리즘
- 손실함수
- 파이싼
- pyenv
- 개발환경
- 티스토리챌린지
- Python
- 백트래킹
- Retrieval
- REST API
- 가상환경
- 신경망 학습
- 밑바닥부터 시작하는 딥러닝
- 경사하강법
- 9020
- 백준
- 기계학습
- 15649
- 재귀
- streamlit
- BOJ
- n과 m
- N-Queen
- video retireval
- 4948
- 1101
- end to end
- 오블완
- 파이썬
- Today
- Total
파이톨치
[BOJ][Python][15649] N과 M(1) 본문
[문제 및 출처]
https://www.acmicpc.net/problem/15649
15649번: N과 M (1)
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해
www.acmicpc.net
[어떻게 풀까?]
이 문제는 백트래킹 문제라고 한다. 사실 나는 백트래킹이고 뭐고 다 재귀 같다. 내가 초보자라서 그런지는 몰라도 비슷비슷한 것 같다. 그래서 카테고리도 그냥 재귀에 넣었다. 아무튼
이 문제를 풀다 열심히 고민을 하다 잘 풀리지 않아서, 여러 유튜브와 블로그들을 찾아보았다.
많이 사람들이 Bool형 배열을 이용하여 이를 푸는 것을 보았다. 변수의 이름은 마치 동사처럼 사용하는 것도 보았는데 이것을 사용하면
코드를 좀 더 현실세계의 언어와 비슷하게 짤 수 있었다.
사실 나도 이 문제가 너무 어렵고 감이 안 잡혀서 코드를 보고 이해하고 다시 생각했다.
이 글을 보는 당신도 잘 이해가 되지 않는다면 일단 코드를 보고 분석해 보길 바란다.
[코드]
N, M = map(int, input().split())
used = [False] * (N+1)
answer = []
def dfs(N, M):
#조건에 충족하면 출력
if len(answer) == M:
print(" ".join(map(str, answer)))
return
for i in range(1, N+1):
if not used[i]:
used[i] = True
answer.append(i)
dfs(N, M)
#다시초기화
used[i] = False
answer.pop()
dfs(N, M)
[코드 설명]
백트래킹은 재귀함수와 마찬가지로 함수를 이용해서 문제를 효과적으로 해결한다. 일단 처음에는 N번 반복해 준다. N번 반복하는 과정에서는 또 다시 dfs함수를 호출 해 준다. 이 과정에서 나는 사용된 값에 표시를 해 두었기 때문에 사용된 값은 재사용되지 않는다. 이 과정을 진행하다가 조건을 충족시키면 출력을 해준다. 그러곤 다시 #다시 초기화 부분을 진행해서 마지막 값을 없앤 다음에 반복문을 진행한다. 그렇게 해서 다시 상위 반복문으로 또 다시 상위 반복문으로 가게 된다.
사실 그림으로 이해하면 정말 편하겠지만 내가 아이패드나 기타 그림을 그릴만한 수단은 부족해서 그림은 못그리겠다. 여러분은 머릿속으로 그리든 인터넷으로 찾아보든 알아서 하시길 바라겠다.
'알고리즘' 카테고리의 다른 글
[BOJ][Python] [15651] N과 M(3) (0) | 2021.07.30 |
---|---|
[BOJ][Python] 15650 N과 M(2) (0) | 2021.07.29 |
[BOJ][Python][10989] 카운팅 정렬 (0) | 2021.07.24 |
[백준][python][1002] 터렛 (0) | 2021.07.18 |
[백준][python][9020] 골드바흐의 추측 (0) | 2021.07.15 |