문제 링크
https://www.acmicpc.net/problem/15649
문제
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
입력
첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다.
중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
예제
입력
4 2
출력
1 2
1 3
1 4
2 1
2 3
2 4
3 1
3 2
3 4
4 1
4 2
4 3
정답 및 풀이
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
visited = [False] * (n + 1)
result = []
def dfs():
if len(result) == m:
print(*result)
return
for i in range(1, n + 1):
if not visited[i]:
visited[i] = True
result.append(i)
dfs()
result.pop()
visited[i] = False
dfs()
- n, m = map(int, input().split())
- 1부터 n까지의 수 중에서 길이가 m인 수열을 만들기 위한 입력값
- visited = [False] * (n + 1)
- 숫자의 중복 사용을 막기 위한 방문 체크 배열
- 인덱스를 숫자 그대로 사용하기 위해 n+1 크기
- result = []
- 현재 선택된 숫자들을 저장하는 리스트 (수열)
- def dfs():
- 백트래킹(DFS) 방식으로 모든 경우의 수를 탐색하는 함수
- if len(result) == m:
- 수열의 길이가 m이 되면 하나의 완성된 경우
- print(*result)
- 리스트를 공백 기준으로 출력
- for i in range(1, n + 1):
- 1부터 n까지 모든 숫자를 순회하며 선택 시도
- if not visited[i]:
- 아직 사용하지 않은 숫자인 경우만 선택
- visited[i] = True
- 숫자 i를 사용했다고 표시
- result.append(i)
- 현재 수열에 숫자 i 추가
- dfs()
- 다음 자리 숫자를 선택하기 위해 재귀 호출
- result.pop()
- 이전 상태로 되돌리기 (백트래킹 핵심)
- visited[i] = False
- 숫자 i를 다시 사용할 수 있도록 방문 해제
- dfs()
- 탐색 시작
새롭게 배운 내용 및 느낀점
- 백트래킹 (Backtracking)
- 모든 경우의 수를 탐색하되, 조건에 맞지 않으면 되돌아감
- DFS (Depth First Search)
- 깊이 우선 탐색 방식으로 수열을 하나씩 완성해 나감
- visited 배열
- 같은 숫자가 중복해서 사용되지 않도록 관리
'백준' 카테고리의 다른 글
| [백준] 25501 : 재귀의 귀재 (Python/파이썬) (0) | 2026.01.02 |
|---|---|
| [백준] 10870 : 피보나치 수 5 (Python/파이썬) (0) | 2026.01.02 |
| [백준] 27433 : 팩토리얼 2 (Python/파이썬) (0) | 2026.01.02 |
| [백준] 24511 : queuestack (Python/파이썬) (0) | 2026.01.02 |
| [백준] 20920 : 영단어 암기는 괴로워 (Python/파이썬) (0) | 2026.01.02 |