15649 N과 M(1) 재귀 너무 어려웡~

코린이서현이·2024년 3월 24일
0

📌 재귀

  • 객체는 참조되기 때문에 재귀 함수가 종료되어도, 살아있다.

문제

자연수 N과 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.

  • 1부터 N까지 자연수 중에서 중복 없이 M개를 고른 수열

수열은 순서가 존재하고 중복이 가능하다. [2,2,2] 가능 [1,2] 랑 [2,1] 은 다른 수

입력

첫째 줄에 자연수 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

문제 풀이

아무리 내가 바보라고 해도, 이건 DFS랑 뭔가가 필요하겠다는 생각은 든다..^^ 하지만 바보라서 어떻게 구현하는지는 처참하게 모르겠다..

분명 DFS를 사용했지만 너무 어려운걸 어떻게??

일단 이 문제의 핵심은

  • 그래프 형식이 아니라는 것!, 나에게는 꽤 어려웠고용
  • 또 순열이라 순서가 있다는 점이었다.
  • 길이가 정해져있음 ⇒ 즉, 백트래킹 문제이고, 길이를 넘어가면 탈출!!

일반 리스트 + DFS 로 순열만들기

재귀문의 형식은 다음과 같다.

(방문리스트)
(순열)

재귀함수!
	순열의 길이가 조건을 만족하면 -> 탈출
	
	for문으로 
		방문되지 않은 애들을 순열에 담자. 
		담은 애는 방문 리스트에 넣자
		-- 재귀함수로 지금 방문 리스트 넣구, 순열도 넣자--
		지금 단계에서 다음 큰 수 넣게 아까 뺀 애 넣자.
		뒤에 단계에서 또 써애하니까 순열에서 빼자.
		

✅ 방문리스트와 순열은 언제까지 유의미한가!!

→ 재귀함수 호출 바깥의 방문리스트와 순열에는 영향을 주지 않는다

문제 코드

import sys
from collections import deque

def creating_a_sequence(a_list,visited,sequence,length):
    if len(sequence) == length:
        print(' '.join(list(map(str,sequence))))
        return
    for i in a_list:
        if visited[i-1] == 0:
            visited[i-1] = 1
            sequence.append(i)
            creating_a_sequence(a_list,visited,sequence,length)
            visited[i-1] = 0
            sequence.pop()

n,m = map(int, sys.stdin.readline().strip().split(" "))
a_list = range(1,n+1)
visited = [0] * n
sequence = deque()

creating_a_sequence(a_list,visited,sequence,m)
profile
24년도까지 프로젝트 두개를 마치고 25년에는 개발 팀장을 할 수 있는 실력이 되자!

0개의 댓글