문제
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열
입력
첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
n,m = map(int,input().split())
rs = []
def rec():
if len(rs) == m:
print(' '.join(map(str,rs)))
return
else:
for i in range(1,n+1):
if i not in rs: #본인을 제외한, 이미 배열에 없는
rs.append(i) #[1]
rec()
rs.pop()
return
rec()
처음에 도움을 받아서 풀었었는데 그때도 분명하게 이해되지 않았다.그래서 시간이 지나고 다시 풀어봤다. 백트래킹의 가장 기초적인 형태인데 함수 내부에서 위의 가지치기 (if문)으로 특정 조건일때 원하는 결과를 출력하고, 그 외 나머지 경우 (else문)는 for을 통해 재귀로 스택에 쌓이면서 하나씩 깊게 파고 들어가면서 (dfs: depth first search)결국엔 끝까지 탐색한다.
이 문제에서 눈 여겨볼 부분은 자신과 중복되는 숫자는 출력하면 안된다는 것이다.
그걸 ‘if i not in rs’로 걸러주었다.