본문 바로가기
프로그래머스 코딩테스트 문제/Level 1

[프로그래머스] - 기사단원의 무기(C#)

by jyppro 2023. 9. 10.

기사단원의 무기

오늘은 "기사단원의 무기" 문제를 풀어보도록 하겠습니다. 해당 문제가 마지막 60% 정답률의 문제입니다. 다음부터는 57%로 한번에 떨어지게 됩니다. 문제 이름만 보면 게임코딩에 유용하게 사용될 것 같은 느낌입니다. 바로 문제 살펴보도록 하겠습니다.

 

문제 설명

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

 

입출력 예 설명

입출력 예 #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 합니다.

 

시작 코드

using System;

public class Solution {
    public int solution(int number, int limit, int power) {
        int answer = 0;
        return answer;
    }
}

 

나의 풀이

using System;

public class Solution {
    public int solution(int number, int limit, int power) {
        // 1부터 number까지, 기사번호의 약수 개수에 해당하는 공격력을 가진 무기 구매, 공격력 제한
        // 공격력 제한을 넘는 기사는 고정 공격력 무기 구매, 무기 공격력당 1kg 철 필요
        // 기사단원의 수 : number, 공격력 제한 : limit, 제한초과 시 고정 공격력 : power
        // 무기를 전부 만들기 위해 필요한 철의 무게 리턴
        int answer = 0;
        int[] cnt = new int[number + 1];
        for(int i = 1; i <= number; i++)
        {
            for(int j = i; j <= number; j += i)
            {
                cnt[j]++;
            }
        }
        
        for(int i = 1; i <= number; i++)
        {
            if(cnt[i] > limit)
                answer += power;
            else
                answer += cnt[i];
        }
        
        return answer;
    }
}

 

코드 분석

int형으로 number, limit, power가 주어지며 코드가 시작됩니다. int형 배열 cnt를 만들어 크기를 number + 1로 지정해줍니다. 이중for문을 만들어 바깥에는 i = 1부터 number까지 안에는 j = i 부터 마찬가지로 number까지인데 두번째 for문은 j에 i를 올려주는 방식입니다. 이중for문을 통해서 cnt[j]를 올려주고, 바깥에 다음 for문을 다시 만납니다. i = 1 부터 number까지 돌리는 for문 안에 if else문을 통해 cnt[i]가 limit보다 크면 answer에 power를 더하고 아니라면 answer에 cnt[i]를 더합니다.

모든 과정을 거쳤다면 answer값을 리턴하면서 코드가 종료됩니다.

 

풀이 설명

이번 문제에서 원하는 답은 무기를 모두 만들기 위해 필요한 철의 무게입니다. 하지만 여기에는 여러 조건이 걸려있습니다. 조건을 요약하자면, 기사는 순서대로 지정된 번호에 대한 약수의 개수로 무기의 공격력을 배정받아 사용할 수 있는데, 최대 제한보다 높다면, power에 맞춘 무기를 사용해야 한다는 것입니다. 그리고 무기를 만들때 공격력1당 1kg의 철이 들어갑니다.

 

이제 풀이를 살펴보면, 처음 등장하는 이중for문을 통해서 기사단원의 번호에 따른 약수의 개수를 구합니다. 이후 다음 for문에서 기사단원 1번부터 제한과 비교하여 무기의 공격력을 answer에 전부 더해 사용해야 하는 철의 무게를 구합니다.

 

<NEXT>

오늘은 "기사단원의 무기" 문제를 풀어보았습니다. 다음에는 2021 Dev-Matching: 웹 백엔드 개발자(상반기) 문제로 출제되었던 "로또의 최고순위와 최저순위" 문제를 다뤄보도록 하겠습니다. 감사합니다.