https://www.acmicpc.net/problem/15663
15663번: N과 M (9)
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다. 수열은 사전 순으로 증가하는 순서로 출력해
www.acmicpc.net
문제
N개의 자연수와 자연수 M이 주어졌을 때, 아래 조건을 만족하는 길이가 M인 수열을 모두 구하는 프로그램을 작성하시오.
- N개의 자연수 중에서 M개를 고른 수열
입력
첫째 줄에 N과 M이 주어진다. (1 ≤ M ≤ N ≤ 8)
둘째 줄에 N개의 수가 주어진다. 입력으로 주어지는 수는 10,000보다 작거나 같은 자연수이다.
출력
한 줄에 하나씩 문제의 조건을 만족하는 수열을 출력한다. 중복되는 수열을 여러 번 출력하면 안되며, 각 수열은 공백으로 구분해서 출력해야 한다.
수열은 사전 순으로 증가하는 순서로 출력해야 한다.
예제 입력 1
3 1
4 4 2
예제 출력 1
2
4
예제 입력 2
4 2
9 7 9 1
예제 출력 2
1 7
1 9
7 1
7 9
9 1
9 7
9 9
풀이 방법

조건
- 방문한 곳은 다시 방문하지 안는다.
- 같은 레벨(depth)에서 중복되면 방문하지 안는다.
조건 1은 N과 M하면서 많이 연습해왔으니 넘어가겠습니다.
조건 2를 보고 위의 그래프 그림을 보면 규칙이 보입니다. 이 그래프는 같은 레벨에서 오름차순으로 정렬되어 있기 때문에
같은 레벨에서 제일 마지막으로 탐색한 노드를 기억해 놓고 새로 탐색할 곳과 비교하면 됩니다.
코드
let NM = readLine()!.split(separator: " ").map{ Int(String($0))! }
let numbers = readLine()!.split(separator: " ").map{ Int($0)! }.sorted()
var answer = [String](repeating: "", count: NM[1])
var out = ""
var visited = Array(repeating: false, count: 10)
func dfs(depth: Int) {
var beforeNum = 0
// '다음 depth'로 넘어와서 종료 조건이 되는지 검사
if depth == NM[1] {
out += answer.joined(separator: " ")
out += "\n"
return
}
// 옆으로 노드를 늘리기 위한 for문
for i in 0..<numbers.count {
// '같은 depth에서' 방문 했엇는지 혹은 직전 노드가 이번에 탐색할 노드랑 같은지 검사
if !visited[i] && beforeNum != numbers[i] {
visited[i] = true
answer[depth] = String(numbers[i])
beforeNum = numbers[i]
dfs(depth: depth + 1)
visited[i] = false
}
}
}
dfs(depth: 0)
print(out)
반응형
'알고리즘 > 그래프 탐색(DFS)' 카테고리의 다른 글
백준 15657 N과 M(8) - Swift (0) | 2022.03.16 |
---|---|
백준 15656 N과 M(7) - Swift (0) | 2022.03.13 |
백준 15655 N과 M (6) - Swift (0) | 2022.03.11 |
백준 15654 N과 M(5) - Swift (0) | 2022.03.11 |
백준 15652 N과 M(4) - Swift (0) | 2022.03.08 |