본문 바로가기
알고리즘/알고리즘 설명

20230731 [Java] 문제풀이

by JayAlex07 2023. 7. 31.

20230731 [Java] 문제풀이

 

 

[프로그래머스] 과제 진행하기

 

하면서 혼자서 디버깅을 계속 하다가, 왜 에러가 뜨는지 찾을 수 있었다

  • 값을 출력하면서 디버깅 계속하는 습관 들이기!!!

 

일단 시작 시간을 시:분 에서 분으로 만들어 놓는다

 

그리고 다음 과제를 시작할 때에, 현재 과제를 못 끝내면, 현재 과제를 스택에 넣는다

 

그리고 만약 다음 과제를 끝내기 전에 현재 과제를 끝냈으면 스택에 넣지 않는다

  • 대신 다음 과제를 시작하기 전에 시간이 남고, 스택에 과제가 있으면, 그 과제를 진행한다

 

계속 틀렸던 부분은 while문에서 스택에서 과제를 꺼냈는, 다음 과제를 시작하기 전에 못 끝냈을 때 (else부분)에 break를 넣지 않아서 계속 틀렸다

import java.util.*;

class Homework{
    public String subject;
    public int start;
    public int time;

    public Homework(String s, int sT, int time) {
        this.subject = s;
        this.start = sT;
        this.time = time;
    }

}

class Solution {

    public ArrayList<String> solution(String[][] plans) {

        ArrayList<String> answer = new ArrayList<String>();

        ArrayList<Homework> array = new ArrayList<>();
        Stack<Homework> stack = new Stack<Homework>();

        // homework 객체를 만들어서 array에 넣기
        // 시간 같은 경우 분으로 맞춰서 homework.start에 저장하기
        for (String[] plan : plans) {
            String[] sT = plan[1].split(":");
            int startTime = Integer.parseInt(sT[0]) * 60 + Integer.parseInt(sT[1]);
            Homework homework = new Homework(plan[0], startTime, Integer.parseInt(plan[2]));
            array.add(homework);
        }

        // 과제 시작 시간 기준으로 정렬하기
        Collections.sort(array, (x1, x2) -> x1.start - x2.start);

        Homework beforeTime = array.get(0);

        for (int i = 1; i < array.size(); i++) {

            Homework currentTime = array.get(i);

            // 다음 과제가 시작하기 전에, 현재 과제를 끝낼 수 있는 경우
            if (beforeTime.time + beforeTime.start <= currentTime.start) {
                answer.add(beforeTime.subject);

                // 다음 과제를 시작하기 전에, 현재 과제를 끝내고 시간이 남는 경우
                int posWorkTime = currentTime.start - (beforeTime.time + beforeTime.start);

                // 스택에서 과제가 있으면 하나씩 빼서, 다음 과제를 시작하기 전에, 최대한 많은 과제를 끝내려고 해야 한다
                while (posWorkTime > 0) {
                    if (stack.isEmpty()) break;

                    Homework tempH = stack.pop();

                    if (tempH.time <= posWorkTime) {
                        answer.add(tempH.subject);
                        posWorkTime -= tempH.time;
                    } else {
                        tempH.time -= posWorkTime;
                        stack.add(tempH);
                        break;
                    }
                }
            } else {
                // 다음 과제를 시작하기 전에, 현재 과제를 못 끝낼 경우
                beforeTime.time -= (currentTime.start - beforeTime.start);
                stack.add(beforeTime);
            }
            beforeTime = currentTime;

        }

        stack.add(array.get(array.size() - 1));
        while (!stack.isEmpty()) answer.add(stack.pop().subject);

        return answer;
    }
}

 

 

 

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

 

곡갱이는 5개를 캔 후에는 더 이상 사용할 수 없다

  • 사용할 수 있는 곡괭이를 아무거나 하나를 선택한다
  • 한 번 사용하기 시작한 곡괭이를 사용할 수 없을 때까지 사용한다
  • 광물은 주어진 순서대로만 캘 수 있다
  • 광산에 있는 모든 광물을 캐거나, 더 사용할 곡괭이가 없을 때까지 광물을 캔다

 

하나의 곡괭이가 사용할 때에, 5개의 광물을 연속으로 캐는 것이 제일 중요한 포인트다

  • 그래서 광물들을 5개씩 묶고, 5개 씩 더해서 우선 순위를 만들었다
    • 광물들의 피로도는 일단 곡괭이가 돌인 기준으로 세웠다
    • 그래야 피로도가 최대인 구간들을 구할 수 있고, 피로도가 제일 심한 구간을 기준으로 내림차순으로 정한다
    • 여기서 중요한 것은 사용할 수 있는 곡괭이가 광물의 구간보다 적을 때에 에러가 뜰 수 있다
      • 곡괭이가 2개 뿐인데, 3개의 구간이 있고, 만약 우선순위 중 3번째 구간이 1등일 때는 성립할 수가 없다
      • 광물은 연속으로 캐야한다
import java.util.*;

class Solution {
    public int solution(int[] picks, String[] minerals) {
        int answer = 0;

        int sumPicks = 0;
        for(int num : picks) sumPicks += num;

        ArrayList<ArrayList<Integer>> newM = new ArrayList<>();

        for (int i = 0; i < Math.ceil((double) minerals.length / 5); i ++) newM.add(new ArrayList<Integer>());

        int idx = -1;
        for (int i = 0; i < minerals.length; i ++) {
            if (i % 5 == 0) idx++;

            if (minerals[i].equals("diamond")) {
                newM.get(idx).add(25);
            } else if (minerals[i].equals("iron")) {
                newM.get(idx).add(5);
            } else {
                newM.get(idx).add(1);
            }
        }

        if (sumPicks < newM.size()) {
            int newArraySize = newM.size() - sumPicks;

            for (int i = 0; i < newArraySize; i++) newM.remove(newM.size() - 1);
        }


        int[][] maxWork = new int[newM.size()][2];

        idx = -1;
        for (int i = 0; i < newM.size(); i ++) {
            maxWork[i][0] = i;

            for (int num : newM.get(i)) {
                maxWork[i][1] += num;
            }
        }

        Arrays.sort(maxWork, (x1, x2) -> x2[1] - x1[1]);

        int maxWorkIdx = 0;
        for (int i = 0; i < 3; i ++) {
            if (maxWorkIdx >= maxWork.length) break;

            for (int j = 0; j < picks[i]; j++) {
                if (maxWorkIdx >= maxWork.length) break;

                for (int k = 0; k < newM.get(maxWork[maxWorkIdx][0]).size(); k++) {
                    if (i == 0) {
                        answer += 1;
                    } else if (i == 1) {
                        if (newM.get(maxWork[maxWorkIdx][0]).get(k) == 25) {
                            answer += 5;
                        } else {
                            answer += 1;
                        }
                    } else { 
                        answer += newM.get(maxWork[maxWorkIdx][0]).get(k);
                    }
                }

                if (picks[i] != 0) {
                    maxWorkIdx ++;
                    if (maxWorkIdx > maxWork.length) break;
                }
            }
        }

        return answer;
    }
}

'알고리즘 > 알고리즘 설명' 카테고리의 다른 글

20230802 [Java] 문제풀이  (0) 2023.08.02
20230801 [Java] 문제풀이  (0) 2023.08.01
20230726 [Java] 문제풀이  (0) 2023.07.26
20230725 [Java] 문제풀이  (0) 2023.07.25
20230720 [Java] 문제풀이  (0) 2023.07.20