본문 바로가기

알고리즘/그래프 탐색(DFS)

백준 N과 M(9) - Swift

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

 

 

풀이 방법

 

조건 

  1. 방문한 곳은 다시 방문하지 안는다.
  2. 같은 레벨(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)' 카테고리의 다른 글