15650번: N과 M (2)
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해
www.acmicpc.net
해결방안
-
대표적인 백트래킹 문제
- 기본적인 조합에 대한 이해가 있으면 좀 더 쉽게 풀 수 있음
알고리즘
-
n, m을 받아옴
- m 크기 만큼의 배열을 초기화 해서 생성
- 즉, 전체 필요한 길이 만큼의 배열을 0으로 일단 초기화
- index와 cnt를 인자로 가지는 함수 정의
- index는 시작지점을 뜻함. 조합의 경우 이전에 갔었던 곳을 다시 재방문 하면 안되기 때문에 시작지점을 뜻하는 index부터 다시 반복문 시작
- cnt는 현재의 위치를 뜻함. 변경되어야 하는 값의 위치를 뜻함
- 배열의 cnt 위치에 i + 1의 값을 넣어줌
- 정의한 함수를 인자에 i + 1, cnt + 1을 넣어 재귀로 다시 실행
- cnt가 현재 원하고자 하는 조합의 길이와 일치할 경우 출력하고 함수 종료
핵심 팁
- 순열 문제에는 visited라는 함수를 이용해서 재귀 함수 전과 후에 방문 처리를 변경하였지만, 여기서는 그럴 필요가 없음
- 어차피 index부터 시작하기 때문에 굳이 체크할 필요가 없음
- 코드로만 보기 보다는 그림을 그려보며 함수를 따라가보면 조금 더 이해가 쉬움
- 백트래킹 방식 말고 라이브러리를 이용해도 가능
- from itertools import combinations
# 조합문제
n, m = map(int, input().split())
arr = [0] * m
def comb(index, cnt):
if cnt == m:
print(" ".join(map(str, arr)))
return
# 처음부터가 아닌 그 자리부터 다시 시작 함으로써 조합 가능하게 해줌
for i in range(index, n):
arr[cnt] = i + 1
comb(i + 1, cnt + 1)
# 순열에서는 visited가 필요하지만 조합에서는 필요 없음
# visited[i] = False
comb(0, 0)
*퍼가신다면 출처와 댓글 부탁드립니다.
*더 많은 자료는 아래 github에 있습니다
https://github.com/griffinGC/Algoritm_PS
'알고리즘' 카테고리의 다른 글
[백준 1759 골드5] 암호 만들기 (0) | 2021.02.17 |
---|---|
[백준 1004 실버3] 어린 왕자 (0) | 2021.02.13 |
[백준 1987 골드4] 알파벳 (0) | 2021.02.06 |