Algorithm/BOJ
백준 15649 N과 M(1)
삼쓰 웅쓰
2021. 1. 28. 11:29
728x90
출처: https://www.acmicpc.net/problem/15649
분류: 백트래킹
접근방식
1~N까지의 수 중에서 중복없이 해당 길이의 모든 경우의 수를 다 찾는 문제였습니다.
가능한 모든 경우의 수를 다 고려하는 백트래킹으로 해결했습니다.
처음엔 원하는 길이만큼 만들어 나가는 dfs를 1~N을 시작점으로 해서 여러 번 돌리는 방식으로 풀었는데요
백트래킹을 공부하고 정통적인 방법으로 다시 풀어봤습니다.
해결방법
1 ~ N을 시작으로 해서 주어진 길이만큼의 배열을 만들어나가는 dfs 방식입니다.
protocol Readable {
func readSingleValue() -> String
func readArray(with separator: Character) -> [String]
}
extension Readable {
func readSingleValue() -> String {
return readLine()!
}
func readSingleValue() -> Int {
return Int(readLine()!)!
}
func readArray(with separator: Character) -> [String] {
return readLine()!.split(separator: " ").map { String($0) }
}
func readArray(with separator: Character) -> [Int] {
return readLine()!.split(separator: " ").map { Int(String($0))! }
}
}
// MARK: 백트래킹
class BOJ15649: Readable {
func input() {
let data: [Int] = readArray(with: " ")
n = data[0]
length = data[1]
}
// MARK: Properties
var n: Int!
var length: Int!
// MARK: Solution
func solution() {
input()
for i in 1...n {
track(num: i, numbers: [i])
}
}
func track(num: Int, numbers: [Int]) {
guard numbers.count < length else {
print(numbers.reduce(into: "", { $0 += "\($1) "}).dropLast())
return
}
guard num <= n else { return }
for i in 1...n where !numbers.contains(i) {
track(num: i, numbers: numbers + [i])
}
}
}
BOJ15649().solution()
정통적인 백트래킹 풀이로 isUsed 변수를 사용해 자리수를 채워가는 방식의 풀이입니다.
protocol Readable {
func readSingleValue() -> String
func readArray(with separator: Character) -> [String]
}
extension Readable {
func readSingleValue() -> String {
return readLine()!
}
func readSingleValue() -> Int {
return Int(readLine()!)!
}
func readArray(with separator: Character) -> [String] {
return readLine()!.split(separator: " ").map { String($0) }
}
func readArray(with separator: Character) -> [Int] {
return readLine()!.split(separator: " ").map { Int(String($0))! }
}
}
class BOJ15649_N과M1: Readable {
func input() {
let data: [Int] = readArray(with: " ")
n = data[0]
array = [Int](repeating: 0, count: data[1])
isUsed = [Bool](repeating: false, count: n+1)
}
// MARK: Properties
var n: Int!
var array: [Int]!
var isUsed: [Bool]!
// MARK: Solution
func solution() {
input()
backTracking(digit: 0)
}
func backTracking(digit: Int) {
guard digit < array.count else {
print(array.reduce(into: "", { $0 += "\($1) "}))
return
}
for i in 1...n {
guard !isUsed[i] else { continue }
isUsed[i] = true
array[digit] = i
backTracking(digit: digit+1)
isUsed[i] = false
}
}
}
BOJ15649_N과M1().solution()
배운점
맞았다고 좋아하지 말고 어떻게 풀었는지, 어떻게 접근했는지를 곱씹어 보고 생각하자.