Home [백준 15650] N과 M(2) 파이썬 풀이 - 백트래킹
Post
Cancel

[백준 15650] N과 M(2) 파이썬 풀이 - 백트래킹

main-img

문제

문제 링크 : 백준 15650

문제


한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.


접근

dfs에서 살짝 변형해주면 된다고 생각했다.
왜냐하면 dfs(깊이 우선 탐색)을 통해 결국 1부터 주어진 n까지는 전부 확인해야하기 때문이다.
대신 m의 길이가 주어지기 때문에 재귀를 통해 dfs를 실행하더라도 해당 재귀는 m길이만큼이 되면 중단한다.


풀이

기본적으로 1부터 순차적으로 접근해야하기에 dfs(1)로 시작한다.

  1. 매번 현재 dfs에 들어온 수부터 n까지 반복한다.
  2. 출력을 위한 배열(s)에 현재 수가 들어있지 않다면 추가하고 dfs(i)를 한다.
  3. 재귀를 하는데 s의 개수가 m과 같다면 출력하고 재귀 중단한다.
  4. 중단하면 s의 마지막 수를 비운다.
  5. 다 비울 경우 다음 2번으로 돌아가 다시 앞 자리 수부터 시작한다.


그리고 접근하고 풀이한 방식을 예제2 예시로 표현해 봤다. 풀이1

정답 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 15650
import sys

def dfs(c):
  if len(s) == m:
    for j in s:
      print(j, end=" ")
    print()
    return
  for i in range(c, n + 1):
    if i not in s:
      s.append(i)
      dfs(i)
      s.pop()

input = sys.stdin.readline
n, m = map(int, input().split())
s = []
a = []
dfs(1)

느낀점

dfs의 응용버전이라고 볼 수 있는 백트래킹을 다시 해보니깐 감이 처음에는 오지 않았는데
끝까지 검색하지 않고 분기 설정을 통해 더 이상 진행하지 않는 점에서 효율적인 것 같다.
소소한 팁이라면 6~8번까지의 출력코드는 아래의 코드를 통해 간략하게 쓸 수 있다는 점을 찾았다..ㅎㅎ

1
print(' '.join(map(str,s)))
This post is licensed under CC BY 4.0 by the author.

[백준 12865] 평범한 배낭 파이썬 풀이 - DP

[네트워크] OSI 7 계층 (OSI 7 Layer)