문제설명
숫자나라 기사단의 각 기사에게는 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
입출력 예
입출력 예 #1
1부터 5까지의 약수의 개수는 순서대로 [1, 2, 2, 3, 2]개입니다. 모두 공격력 제한 수치인 3을 넘지 않기 때문에 필요한 철의 무게는 해당 수들의 합인 10이 됩니다. 따라서 10을 return 합니다.
입출력 예 #2
1부터 10까지의 약수의 개수는 순서대로 [1, 2, 2, 3, 2, 4, 2, 4, 3, 4]개입니다. 공격력의 제한수치가 3이기 때문에, 6, 8, 10번 기사는 공격력이 2인 무기를 구매합니다. 따라서 해당 수들의 합인 21을 return 합니다.
코드 설명
해당 코드는 주어진 세 개의 정수인 number, limit, power를 사용하여 정수 number보다 작거나 같은 모든 수에 대해 특정 조건을 만족하는 값을 계산하는 문제입니다.
메서드 solution의 동작을 이해하기 위해 코드를 한 줄씩 살펴보겠습니다!
int solution(int number, int limit, int power)
: 메서드 선언으로, number, limit, power라는 세 개의 int형 매개변수를 받습니다. 결과는 int형으로 반환됩니다.
int answer = 0;
: answer라는 변수를 선언하고 0으로 초기화합니다. 이 변수는 결과를 담는 변수로 사용될 것입니다.
for (int i = 1; i <= number; i++) {
: for 반복문을 사용하여 i를 1부터 number까지 1씩 증가시킵니다! 이 루프는 number보다 작거나 같은 모든 수에 대해 연산을 수행할 것입니다.
int cnt = 0;
: cnt라는 변수를 선언하고 0으로 초기화합니다. 이 변수는 특정 수 i에 대해 조건을 만족하는 개수를 세는 역할을 할 것입니다.
for (int j = 1; j * j <= i; j++) {
: 두 번째 for 루프를 사용하여 j를 1부터 i의 제곱근보다 작거나 같은 수까지 증가시킵니다. 이 루프는 i의 약수를 찾기 위해 사용됩니다.
if (i % j == 0) {
: if 문을 사용하여 i가 j로 나누어 떨어지는지 검사합니다. 즉, j가 i의 약수인지 확인합니다.
cnt += (j * j == i) ? 1 : 2;
: cnt에 (j * j == i) ? 1 : 2 값을 더합니다. 이 부분은 i의 약수를 찾을 때마다 cnt를 갱신하는 역할을 합니다.
만약 j가 i의 제곱근인 경우(즉, i가 완전제곱수라면) 약수는 하나만 존재하므로 cnt에 1을 더합니다.
그렇지 않은 경우(즉, i가 완전제곱수가 아니라면) 약수는 두 개 존재하므로 cnt에 2를 더합니다.
if (cnt > limit) cnt = power;
: cnt가 limit보다 크면 cnt를 power로 변경합니다. 이 부분은 약수의 개수가 limit보다 큰 경우, 결과 값에 대한 제한을 주는 역할을 합니다.
answer += cnt;
: cnt를 answer에 더합니다. 이는 i에 대한 약수 개수를 결과에 누적하는 역할을 합니다.
return answer;
: 계산된 결과인 answer를 반환합니다.
소스코드&결과
소스코드
class Solution {
public int solution(int number, int limit, int power) {
int answer = 0;
for(int i = 1; i <= number; i++){
int cnt = 0;
for(int j = 1; j*j <= i; j++){
if(i%j == 0){
cnt += (j*j == i) ? 1 : 2;
}
}
if(cnt > limit) cnt = power;
answer += cnt;
}
return answer;
}
}
실행 결과
다른 사람이 짠 코드
public int solution(int number, int limit, int power) {
int[] count = new int[number + 1];
for (int i = 1; i <= number; i++) {
for (int j = 1; j <= number / i; j++) {
count[i * j]++;
}
}
int answer = 0;
for (int i = 1; i <= number; i++) {
if (count[i] > limit) {
answer += power;
} else {
answer += count[i];
}
}
}
위의 코드는 저랑 다른 방법으로 각 수의 모든 약수를 찾았습니다.
- int[] count = new int[number + 1]; : count라는 길이가 number + 1인 정수형 배열을 선언합니다. count 배열은 0으로 자동 초기화됩니다. 배열의 인덱스는 1부터 number까지의 숫자를 나타냅니다.
- for (int i = 1; i <= number; i++) { : 첫 번째 for 반복문은 i를 1부터 number까지 증가시킵니다. 이 루프는 각각의 i에 대해 모든 약수를 찾는 작업을 수행할 것입니다.
- for (int j = 1; j <= number / i; j++) { : 두 번째 for 반복문은 j를 1부터 number / i까지 증가시킵니다. 이 루프는 i의 배수들을 찾아낼 것입니다. 왜냐하면 i * j는 i의 배수가 되기 때문입니다.
- count[i * j]++; : 두 번째 for 반복문 안에서 i * j 값을 count 배열의 해당 인덱스에 1을 증가시킵니다. 즉, i * j가 i의 배수인 수들의 약수 개수를 세는 것입니다. 이렇게 하면 배열 count에는 각 수의 약수 개수가 저장될 것입니다.
이렇게 count 배열을 채우는 과정을 거치면, count[i]에는 i가 가지고 있는 약수의 개수가 저장되어 있게 됩니다.
이때, 배열 count의 인덱스 i는 수 i의 약수 개수를 나타내게 됩니다. 그리고 이 배열을 기반으로 앞서 설명한 solution 메서드의 cnt 값을 계산하고, 최종적으로 answer에 누적하여 원하는 결과를 얻게 됩니다.
'Coding Test > 프로그래머스' 카테고리의 다른 글
[JavaScript] 최댓값과 최솟값 (0) | 2023.07.30 |
---|---|
[JAVA] 다트 게임 (2) | 2023.07.28 |
[JavaScript] 문자열 내 p와 y의 개수 (2) | 2023.07.25 |
[JavaScript] 음양 더하기 (2) | 2023.07.24 |
[JavaScript] 자릿수 더하기 (0) | 2023.07.24 |