본문 바로가기

알고리즘/프로그래머스

[프로그래머스]Lv.1 기사단원의 무기

https://school.programmers.co.kr/learn/courses/30/lessons/136798

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


문제

  • 숫자나라 기사단의 각 기사에게는 1번부터 number까지 번호가 지정되어 있습니다. 
  • 기사들은 무기점에서 무기를 구매하려고 합니다.
  • 각 기사는 자신의 기사 번호의 약수 개수에 해당하는 공격력을 가진 무기를 구매하려 합니다. 
  • 단, 이웃나라와의 협약에 의해 공격력의 제한수치를 정하고
  • 제한수치보다 큰 공격력을 가진 무기를 구매해야 하는 기사는 협약기관에서 정한 공격력을 가지는 무기를 구매해야 합니다.
  • 예를 들어, 15번으로 지정된 기사단원은 15의 약수가 1, 3, 5, 15로 4개 이므로 공격력이 4인 무기를 구매합니다. 
  • 만약, 이웃나라와의 협약으로 정해진 공격력의 제한수치가 3이고 제한수치를 초과한 기사가 사용할 무기의 공격력이 2라면
  • 15번으로 지정된 기사단원은 무기점에서 공격력이 2인 무기를 구매합니다. 
  • 무기를 만들 때, 무기의 공격력 1당 1kg의 철이 필요합니다. 
  • 그래서 무기점에서 무기를 모두 만들기 위해 필요한 철의 무게를 미리 계산하려 합니다.
  • 기사단원의 수를 나타내는 정수 number와 이웃나라와 
  • 협약으로 정해진 공격력의 제한수치를 나타내는 정수 limit와 
  • 제한수치를 초과한 기사가 사용할 무기의 공격력을 나타내는 정수 power가 주어졌을 때
  • 무기점의 주인이 무기를 모두 만들기 위해 필요한 철의 무게를 return 하는 solution 함수를 완성하시오.

입출력 예제


풀이방식

이번 문제는 약수의 개수를 구하는 문제이다.


설계과정

1. 시간 복잡도를 줄이기 위해 제곱근을 사용하여 0으로 나누어 떨어지는 약수를 찾는다.

  • Math.sqrt() : 제곱근을 반환한다.
  • 제곱근에 대해서는 아래 사이트를 참고해보자.

https://kbw1101.tistory.com/32

 

[알고리즘] 효율적으로 약수를 찾는 알고리즘

코딩테스트 문제 중, 가끔 수학적인 기초를 묻는 문제에 약수, 배수 등의 문제가 출제된다. 이러한 유형의 문제를 접해본 경험이 없는 사람들은 최악의 시간복잡도를 갖는, 모든 경우를 찾는 순

kbw1101.tistory.com

2. 구한 약수 중에서 중복값은 1만 더해주고, 중복값이 아니면 2를 더해준다.

  • 예를 들어 4라는 숫자는 2와 2 가 동일한 수이므로 중복값을 제거해서 1개만 개수로 추가하는 것이다.

3. 해당 기사의 약수의 개수(=공격력)이 제한수치를 넘는다면 협약으로 정해진 공격력의 무기를 구매한다.

4. 넘지 않는다면 공격력의 무기를 구매한다.


풀이과정

1. 결과값을 저장할 변수 answer를 선언하고, 0으로 초기화한다.

 

2. 1부터 number까지 도는 for문을 작성하고 변수 cnt를 0으로 초기화한다.

  • number : 기사단원의 수를 나타내는 정수이다.
  • cnt : 약수의 개수를 저장할 변수이다.

3. 1부터 입력받은 수의 제곱근까지 도는 for문을 작성한다.

  • 시간복잡도를 줄이기 위해 제곱근을 사용했다.
  • 이를 통해 나온 약수를 가지고 입력받은 값을 나누게 될 경우 나오는 결과 역시 약수이기 때문이다.

4. 약수일 때에는 cnt에 2를 더한다.

  • i를 j로 나눈 나머지가 0이라는 것은 j가 약수라는 것을 의미한다.
  • 자기 자신과 약수를 전부 세주어야 하므로 2를 더한다.

5. 단, 중복값이 있을 때에는 cnt에 1을 더한다.

  • 예를 들어 i가 4라고 가정했을때, 2는 4/2 해서 2가 나온다.
  • 이러한 경우에는 2가 중복이 되므로 1개만 더해준다.

6. 해당 기사의 공격력이 제한수치를 넘는다면 협약으로 정해진 공격력의 무기를 구매한다.

 

7. 넘지 않는다면 공격력의 무기를 구매한다.


답안소스

  • 프로그래머스
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<=Math.sqrt(i); j++) {
        		if(i % j == 0) {
        			if(i / j == j) {
        				cnt += 1;
        			} else {
        				cnt += 2;
        			}
        		}
        	}
        	answer = cnt > limit? answer + power : answer + cnt;
        }
        
        return answer;
    }
}

  • 이클립스
import java.util.Scanner;

public class KnightsWeapon {
	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<=Math.sqrt(i); j++) {
        		if(i % j == 0) {
        			if(i / j == j) {
        				cnt += 1;
        			} else {
        				cnt += 2;
        			}
        		}
        	}
        	answer = cnt > limit? answer + power : answer + cnt;
        }
        return answer;
    }
	
	public static void main(String[] args) {
		KnightsWeapon K = new KnightsWeapon();
		Scanner sc = new Scanner(System.in);
		int number = sc.nextInt();
		int limit = sc.nextInt();
		int power = sc.nextInt();
		
		System.out.println(K.solution(number, limit, power));
	}
}