프로그래머스/Lv. 1

[프로그래머스 코딩테스트] 기사단원의 무기(Java)

Sigfriede 2023. 7. 18. 01:00

  문제 설명

  숫자나라 기사단의 각 기사에게는 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

 

  입출력 예

number limit power result
5 3 2 10
10 3 2 21
class Solution {
    public int solution(int number, int limit, int power) {
        int[] array = new int[number + 1];
        for (int i = 1; i <= number; i++) {
            for (int j = 1; j <= (int)Math.sqrt(i); j++) {
                if (i % j == 0) {
                    array[i]++;
                    if (j != i / j) {
                        array[i]++;
                    }
                    if (array[i] > limit) {
                        array[i] = power;
                        break;
                    }
                }
            }
        }
        int answer = 0;
        for (int i = 1; i < array.length; i++) {
            answer += array[i];
        }
        return answer;
    }
}

  배열 array를 생성합니다. 기사단원의 공격력을 담을 것입니다. 기사단원은 1번부터 시작하기 때문에 크기에 기사단원의 수 + 1로, 배열의 0번 인덱스는 사용하지 않습니다.

  바깥 for문이 1부터 number까지 순회합니다.

  안쪽 for문이 1부터 Math 클래스의 sqrt 메소드를 이용하여 i의 제곱근까지 순회합니다. i의 약수를 구하되, 제곱근까지만 구하는 이유는 약수는 대칭으로 존재한다는 특징 때문입니다. sqrt는 double형으로 반환하므로 int로 명시적으로 형변환을 해줍니다.

  바깥 if문에서 i를 j로 나눈 나머지가 0이라면, 즉 j가 i의 약수라면 array의 i 번째 원소가 증가합니다.

  안쪽 첫 번째 if문에서 j가 i를 j로 나눈 값과 동일하지 않다면, 즉 j가 i의 약수이면서 중복되지 않는 수라면 array의 i 번째 원소가 증가합니다.

  안쪽 두 번째 if문에서 array의 i 번째 원소가 limit보다 크다면 array의 i 번째 원소에 power를 할당한 뒤 break를 이용하여 안쪽 for문을 종료합니다. 최댓값이 정해져 있기 때문에 이후 계산은 불필요하기 때문입니다.

  for문이 array의 길이만큼 순회합니다.

  answer에 array의 i 번째 원소를 더하기 할당합니다. 이런 식으로 array의 전체 원소의 값의 합을 구하여 반환합니다.