알고리즘/알고리즘 문제풀이
카카오_프로그래머스_양궁대회 swift
Downey
2022. 2. 28. 17:28
https://programmers.co.kr/learn/courses/30/lessons/92342
코딩테스트 연습 - 양궁대회
문제 설명 카카오배 양궁대회가 열렸습니다. 라이언은 저번 카카오배 양궁대회 우승자이고 이번 대회에도 결승전까지 올라왔습니다. 결승전 상대는 어피치입니다. 카카오배 양궁대회 운영위원
programmers.co.kr
접근 방법
- dfs를 사용해서 라이언이 이기거나 지는 모든 경우의 수를 끌어모은다..! 이 때, 어피치보다 점수가 낮은 경우 제외
- 끌어 모은 점수 중 라이언의 점수가 max인 경우를 모두 수집한다.
- 작은 점수가 많은 경우 순으로 정렬한다.
오답 코드
더보기
import Foundation
func sumScore(scores: [Int]) -> Int {
var sum = 0
scores.enumerated().forEach( { (n,c) in
if c != 0 {
sum += 10 - n
}
})
return sum
}
func solution(_ n:Int, _ info:[Int]) -> [Int] {
let apchScore = sumScore(scores: info)
let result = recursion(i: 0, remainShoot: n, ryanInfo: [Int].init(repeating: 0, count: 11), apchInfo: info, apchScore: apchScore)
let test = Array(result)
var maxRyanScore = 0
var maxIndexes: [Int] = []
test.enumerated().forEach({ (n,c) in
let score = sumScore(scores: c)
if score > maxRyanScore {
maxRyanScore = score
maxIndexes = [n]
} else if score == maxRyanScore {
maxIndexes.append(n)
}
})
// for i in maxIndexes {
// print("index: \(i), \(test[i])")
// }
if maxIndexes.count > 2 {
var list = [[Int]].init()
for i in maxIndexes {
list.append(test[i])
}
list.sort(by: {
for i in stride(from: 10, to: 0, by: -1) {
if $0[i] < $1[i] {
return false
}
}
return true
})
return list.first!
}
if maxIndexes.isEmpty {
return [-1]
}
return test[maxIndexes.first!]
}
func recursion(i: Int, remainShoot: Int, ryanInfo: [Int], apchInfo: [Int], apchScore: Int) -> Set<[Int]> {
var sol = Set<[Int]>.init()
var newRyanInfo = ryanInfo
var newRemainShoot = remainShoot
var newApchScore = apchScore
if remainShoot <= 0 {
let ryanScore = sumScore(scores: newRyanInfo)
if ryanScore > apchScore {
sol.insert(newRyanInfo)
return sol
} else {
return [[-1]]
}
}
if i > 10 {
let ryanScore = sumScore(scores: newRyanInfo)
if ryanScore > apchScore {
sol.insert(newRyanInfo)
return sol
} else {
return [[-1]]
}
}
let winOrLose = [false, true] // Ryan기준
for isWin in winOrLose {
if isWin && remainShoot > apchInfo[i] {
newRyanInfo[i] = apchInfo[i] + 1
newRemainShoot -= newRyanInfo[i]
newApchScore -= 10 - i
let result = recursion(i: i+1, remainShoot: newRemainShoot, ryanInfo: newRyanInfo, apchInfo: apchInfo, apchScore: newApchScore)
sol = sol.union(result)
} else {
let result = recursion(i: i+1, remainShoot: newRemainShoot, ryanInfo: newRyanInfo, apchInfo: apchInfo, apchScore: newApchScore)
sol = sol.union(result)
}
}
return sol
}
제출 결과
더보기
테스트 1 〉 | 실패 (1.17ms, 16.5MB) |
테스트 2 〉 | 실패 (16.58ms, 16.4MB) |
테스트 3 〉 | 실패 (15.84ms, 16.4MB) |
테스트 4 〉 | 실패 (8.30ms, 16.5MB) |
테스트 5 〉 | 실패 (13.33ms, 16.7MB) |
테스트 6 〉 | 실패 (14.94ms, 16.4MB) |
테스트 7 〉 | 실패 (4.18ms, 16.6MB) |
테스트 8 〉 | 통과 (3.12ms, 16.4MB) |
테스트 9 〉 | 실패 (6.37ms, 16.4MB) |
테스트 10 〉 | 실패 (5.28ms, 16.4MB) |
테스트 11 〉 | 실패 (5.49ms, 16.3MB) |
테스트 12 〉 | 실패 (4.57ms, 16.4MB) |
테스트 13 〉 | 실패 (11.05ms, 16.5MB) |
테스트 14 〉 | 실패 (7.22ms, 16.6MB) |
테스트 15 〉 | 실패 (11.26ms, 16.5MB) |
테스트 16 〉 | 실패 (5.77ms, 16.6MB) |
테스트 17 〉 | 실패 (6.68ms, 16.3MB) |
테스트 18 〉 | 통과 (1.11ms, 16.4MB) |
테스트 19 〉 | 통과 (0.50ms, 16.5MB) |
테스트 20 〉 | 통과 (14.40ms, 16.6MB) |
테스트 21 〉 | 실패 (16.54ms, 16.4MB) |
테스트 22 〉 | 통과 (13.68ms, 16.5MB) |
테스트 23 〉 | 실패 (1.04ms, 16.3MB) |
테스트 24 〉 | 실패 (23.10ms, 16.6MB) |
테스트 25 〉 | 실패 (21.34ms, 16.6MB) |
반성 및 개선 방향
- 라이언의 점수가 가장 클 경우, 둘의 점수차가 제일 클 것이라고 예상하였으나, 아닌 경우가 있을 수도 있다는 생각이..
- 테스트 케이스를 통과 못하는 경우가 있었다, 이 경우, 화살을 전부 사용하지 않았다. 아마 종료 구문 중, 10번째 과녁까지 간 경우일 것이라고 예상하는데, 이 때 남은 화살을 처리하는 내용이 없기 때문이라고 예상.
- 타인의 코드 중 가장 괜찮아 보인것은, 이기고 지는 완전 탐색이 아니라, 화살을 쏘는 모든 경우의 수를 탐색하는 경우였다. 참조 링크 : https://velog.io/@qodlstjd12/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Kakao-%EC%96%91%EA%B6%81-%EB%8C%80%ED%9A%8C-Java