문제 링크
https://www.acmicpc.net/problem/15652
문제
자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
1부터 N까지 자연수 중에서 M개를 고른 수열
같은 수를 여러 번 골라도 된다.
고른 수열은 비내림차순이어야 한다.
길이가 K인 수열 A가 A1 ≤ A2 ≤ ... ≤ AK-1 ≤ AK를 만족하면, 비내림차순이라고 한다.
입력
첫째 줄에 자연수 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다.
중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
예제
입력
3 3
출력
1 1 1
1 1 2
1 1 3
1 2 2
1 2 3
1 3 3
2 2 2
2 2 3
2 3 3
3 3 3
정답 및 풀이
import sys
input = sys.stdin.readline
n, m = map(int, input().split())
result = []
def dfs(start):
if len(result) == m:
print(*result)
return
for i in range(start, n + 1):
result.append(i)
dfs(i)
result.pop()
dfs(1)
- import sys
- 파이썬 기본 입력보다 빠른 입력 처리를 위해 sys 모듈을 불러옴
- input = sys.stdin.readline
- 입력 속도 향상을 위해 input 함수를 readline으로 재정의
- n, m = map(int, input().split())
- 수열에 사용할 최대 숫자 n과 수열 길이 m 입력
- visited = [False] * (n + 1)
- 숫자의 사용 여부를 체크하기 위한 배열 생성
- 하지만 15652는 중복 허용 문제라 이 배열은 필요 없음
- result = []
- 현재 DFS에서 만들고 있는 수열을 저장하는 리스트
- def dfs():
- 수열을 만들기 위한 DFS 함수 정의
- 시작 숫자를 인자로 받지 않아 오름차순을 유지할 수 없는 구조
- if len(result) == m:
- 현재 수열 길이가 m이 되었는지 확인
- result_sort = sorted(result)
- 완성된 수열을 정렬한 새로운 리스트 생성
- DFS 설계가 잘못되어 사후 검사를 하고 있음
- if result == result_sort:
- 현재 수열이 오름차순인 경우만 출력
- 모든 경우를 만든 뒤 거르는 비효율적인 방식
- print(*result)
- 조건을 만족하는 수열을 출력
- return
- 현재 DFS 종료 후 이전 단계로 복귀
- for i in range(1, n + 1):
- 1부터 n까지 모든 숫자를 탐색
- 이전 값과의 관계를 고려하지 않아 오름차순 보장 불가
- if not visited[i]:
- 방문 여부를 확인
- 하지만 visited 값을 변경하는 코드가 없어 의미가 없음
- result.append(i)
- 현재 숫자를 수열에 추가
- dfs()
- 다음 깊이로 재귀 호출
- 같은 범위를 다시 탐색하여 불필요한 경우의 수 발생
- result.pop()
- 백트래킹을 위해 마지막에 추가한 값 제거
- dfs()
- DFS 탐색 시작
'백준' 카테고리의 다른 글
| [백준] 11047 : 동전 0 (Python/파이썬) (0) | 2026.01.19 |
|---|---|
| [백준] 11659 : 구간 합 구하기 4 (Python/파이썬) (0) | 2026.01.19 |
| [백준] 9461 : 파도반 수열 (Python/파이썬) (0) | 2026.01.15 |
| [백준] 1904 : 01타일 (Python/파이썬) (0) | 2026.01.12 |
| [백준] 15651 : N과 M (3) (Python/파이썬) (0) | 2026.01.11 |