이끌든지 따르든지 비키든지

Software Development/Algorithm

[프로그래머스] 광물 캐기 - JAVA

SeongHo5 2023. 9. 26. 18:08

프로그래머스 코딩 테스트 연습 문제 -  광물 캐기 / JAVA 풀이 정리

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

 

프로그래머스

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

programmers.co.kr


알고리즘

  1. 광물을 5개 단위로 묶고, 묶음마다 대해 돌을 가장 효율적으로 캘 수 있는 곡괭이를 선택한다.
  2. 돌을 가장 많이 캘 수 있는 곡괭이부터 사용하여 광물을 캐고, 해당 곡괭이의 사용 횟수를 감소시킨다.

위 과정을 곡괭이 사용 횟수를 소진할 때까지 반복한다.

(광물이 5개 단위인 이유 : 한 번 곡괭이를 사용하면 소진될 때까지 사용해야하고, 5회 사용할 수 있으니까)


코드 풀이

import java.util.*;	
    
public class Solution {

    static class Mineral {
		private int diamond;
		private int iron;
		private int stone;

		public Mineral(int diamond, int iron, int stone) {
			this.diamond = diamond;
			this.iron = iron;
			this.stone = stone;
		}
	}
	static int[][] scoreBoard;
	static List<Mineral> list;

 

계산에 사용할 클래스와 변수를 미리 선언해준다.

 

public int solution(int[] picks, String[] minerals) {
		int answer = 0;
		
		// 각각 다이아 & 철 & 돌 곡괭이로 다이아, 철, 돌을 캘 때 피로도
		scoreBoard = new int[][]{{1, 1, 1}, {5, 1, 1}, {25, 5, 1}}; 

		int totalPicks = Arrays.stream(picks).sum();

		list = new ArrayList<>();
		// minerals를 5개씩 묶는다.
		for(int i = 0; i < minerals.length; i += 5) {
			if(totalPicks == 0) break;
			int dia = 0, iron = 0, stone = 0;
			for(int j = i; j < i + 5; j++) {
            
				// 더 이상 캘 광물이 없으면 break
				if(j == minerals.length) break;
                
				String mineral = minerals[j];
				// 5개 묶음에 광물이 각각 몇 개씩 있는지 count
				int val = mineral.equals("iron") ? 1 : mineral.equals("stone") ? 2 : 0;
				dia += scoreBoard[0][val];
				iron += scoreBoard[1][val];
				stone += scoreBoard[2][val];
			}
			list.add(new Mineral(dia, iron, stone));
			totalPicks--;
		}

 

곡괭이 종류별로 광물을 캘 때의 피로도를 선언해주고,

광물 묶음별로 다이아 · 철  · 돌 곡괭이를 사용했을 때 필요한 피로도를 계산해 list에 담아준다.

 

Collections.sort(list, ((o1, o2) -> (o2.stone - o1.stone)));
		
		for(Mineral m : list) {
			int dia = m.diamond;
			int iron = m.iron;
			int stone = m.stone;

			if(picks[0] > 0) {
				answer += dia;
				picks[0]--;
				continue;
			}
			if(picks[1] > 0) {
				answer += iron;
				picks[1]--;
				continue;
			}
			if(picks[2] > 0) {
				answer += stone;
				picks[2]--;
				continue;
			}
		}

		return answer;
	}

 

곡괭이 수만큼 계산한 list를 컬렉션을 사용해 내림차순으로 정렬하고,

현재 남아있는 곡괭이 중 가장 최선의 결과를 낼 수 있는 곡괭이를 사용했을 때의 피로도를 합산해주면 된다.