문제 설명
숫자나라 기사단의 각 기사에게는 1번부터 number까지 번호가 지정되어 있습니다. 기사들은 무기점에서 무기를 구매하려고 합니다.
각 기사는 자신의 기사 번호의 약수 개수에 해당하는 공격력을 가진 무기를 구매하려 합니다. 단, 이웃나라와의 협약에 의해 공격력의 제한수치를 정하고, 제한수치보다 큰 공격력을 가진 무기를 구매해야 하는 기사는 협약기관에서 정한 공격력을 가지는 무기를 구매해야 합니다.
예를 들어, 15번으로 지정된 기사단원은 15의 약수가 1, 3, 5, 15로 4개 이므로, 공격력이 4인 무기를 구매합니다. 만약, 이웃나라와의 협약으로 정해진 공격력의 제한수치가 3이고 제한수치를 초과한 기사가 사용할 무기의 공격력이 2라면, 15번으로 지정된 기사단원은 무기점에서 공격력이 2인 무기를 구매합니다. 무기를 만들 때, 무기의 공격력 1당 1kg의 철이 필요합니다. 그래서 무기점에서 무기를 모두 만들기 위해 필요한 철의 무게를 미리 계산하려 합니다.
기사단원의 수를 나타내는 정수 number와 이웃나라와 협약으로 정해진 공격력의 제한수치를 나타내는 정수 limit와 제한수치를 초과한 기사가 사용할 무기의 공격력을 나타내는 정수 power가 주어졌을 때, 무기점의 주인이 무기를 모두 만들기 위해 필요한 철의 무게를 return 하는 solution 함수를 완성하시오.
제한사항
- 1 ≤ number ≤ 100,000
- 2 ≤ limit ≤ 100
- 1 ≤ power ≤ limit
내가 푼 풀이
약수의 갯수를 구해서 limit을 초과하면 기본공격력 power 만큼 더하고, 초과하지 않으면 약수의 갯수만큼 더해서 출력한다.
이 문제에서 주어지는 number는 100,000 까지 제공한다.
일반적인 약수의 갯수를 구하는방법은
숫자 n 이 주어졌을때, 1부터 n까지 나누어 떨어지면 약수이고 그 갯수를 구하는것이 일반적인 방법이다
하지만 이 방법은 2중 반복문 안에서 갯수를 구하므로 ( O(n^2) ) 시간초과가 날 경우가 많다.
이 문제 역시 모든 숫자를 순회해서 약수를 구하는 방법을 이용하면 시간초과가 뜬다.
그래서 약수를 구하는 더 효율적인 방법을 이용해야한다.
여러가지가 있겠지만 그 중 하나는 범위를 좁히는것이다.
숫자 n 이 주어졌을때, n의 제곱근까지 확인한다.
이전에 소수를 효율적으로 구하는 과정이랑 비슷한데,
10의 약수 2 는 2 x 5 = 10이지만 10의 약수 5 도 역시 5 x 2 = 10 이다.
갯수는 2개지만 표현식은 앞뒤만 다를뿐 결국 같다는것을 이용하는 것이다
그리고 제곱근이 정수로 딱 떨어지는 경우, ex) 100
1 x 100 = 100
2 x 50 = 100
4 x 25 = 100
5 x 20 = 100
10 x 10 = 100
20 x 5 = 100
25 x 4 = 100
50 x 2 = 100
100 x 1 = 100
10 x 10 을 기준으로 대칭을 이루고 있다.
정수 n의 제곱근이 정수로 떨어지는 경우 num * num == n 인경우 횟수 증가한다.
이 방법의 시간복잡도는 O(√N) 으로 이전에 쓰는 일반적인 방법보다 시간이 훨씬 단축된다.
import Foundation
func solution(_ number:Int, _ limit:Int, _ power:Int) -> Int {
var result = 0
for i in 1...number {
var num = 1
var count = 0
while num * num <= i {
if (num * num) == i {
count += 1
} else if i % num == 0 {
count += 2
}
num += 1
}
if count > limit {
result += power
} else {
result += count
}
}
return result
}
약수의 개수 구하기 알고리즘 참고:
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
푸드 파이트 대회 Swift (0) | 2023.04.10 |
---|---|
과일 장수 Swift (0) | 2023.04.10 |
명예의 전당 (1) Swift (0) | 2023.04.10 |
문자열 나누기 Swift (0) | 2023.04.10 |
가장 가까운 같은 글자 Swift (0) | 2023.04.09 |