Algorithm/Java

[백준/JAVA] 22864번 : 피로도

dbfl9911 2024. 10. 26. 13:52
반응형

https://www.acmicpc.net/problem/22864

 

📌 문제 요약 

하루 24시간 동안 1시간 단위로 일을 하거나 쉴 수 있으며, 일할 때는 피로도가 증가하고 처리량이 늘어납니다. 피로도가 최대치인 M을 초과하지 않도록 하면서 최대한 많은 일을 처리하는 것이 목표입니다.

 

  1. 일을 할 때: 피로도가 A만큼 증가하고, 처리량은 B만큼 증가.
  2. 쉴 때: 피로도가 C만큼 감소하고, 처리량에는 변화가 없음.
  3. 피로도가 0 이하가 되면 0으로 유지됨.
  4. 하루는 24시간이며, 피로도가 M을 넘으면 일할 수 없음.

 



[ 오답 노트 ]


❌ 기존 오답 코드

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int A = Integer.parseInt(st.nextToken()); // 5
        int B = Integer.parseInt(st.nextToken()); // 3
        int C = Integer.parseInt(st.nextToken()); // 2
        int M = Integer.parseInt(st.nextToken()); // 10
        
        int fatigue = 0; // 피로도
        int work = 0; // 일 하는 시간
        int answer = 0; // 일의 처리량
        int time = 0; // 원래 시간?

        while(work <= 24) {
            work += 1;
            // 1시간 일하면
            // => 이전 시간과 비교했을 때 1 증가했다면
            if(time < work) {
                fatigue += 5;
                answer += 3;
            }

            // 1시간 쉰다면
            // => 이전 시간과 비교했을 때 1 감소했다면
            if(time > work) {
                fatigue -= 2;
            }

            // 피로도가 음수로 내려가면 0으로 바뀜
            if(fatigue < 0) {
                fatigue = 0;
            }

            // 피로도 10 넘게 일하면 그만둠
            if(fatigue > 10) {
                break;
            }

        }

        System.out.println(answer);

    }
}



📌 기존 코드의 문제점

 

1. 루프 조건 설정 문제

work <= 24 조건을 사용했지만, work는 실제 시간과 일한 시간을 혼동하게 만듭니다. time < 24 조건이 더 적절합니다.

 

2. 시간과 일의 분리 부족

work 변수를 일하는 시간으로 사용하면서 time과 혼동되었습니다.

 

3. 피로도 및 처리량 업데이트 오류

문제 조건에 따라 피로도와 일을 제대로 관리하지 않았습니다. fatigue + A <= M 조건을 통해 작업 가능 여부를 판단해야 합니다.

 

4. 코드 가독성 부족

변수 이름과 로직이 복잡하게 얽혀 있어 코드를 이해하기 어렵게 만듭니다.

 




[ 정답 코드 & 올바른 풀이 ]

📌 올바른 풀이

1. for 루프를 통해 24시간 동안 반복하며 필요한 변수는 현재 피로도와 총 처리한 일의 양 두가지만 사용

하루는 24시간이므로 for 루프를 사용해 간단하게 처리합니다.

 

2. 일을 할 수 있는 경우와  쉬어야 하는 경우의 두가지 경우의 수로 나눠 처리

2-1.  피로도를 최대한 M을 넘지 않는단 조건을 이용  작업 가능 여부 판단

fatigue + A <= M 조건을 통해 피로도가 M을 초과하지 않을 때만 작업하도록 합니다.

 

2-2. 피로도 감소 조건 적용

일을 하지 못하는 경우 피로도를 C만큼 감소시키고, 음수일 경우 0으로 유지시킵니다.

 



📌 정답 코드

import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int A = Integer.parseInt(st.nextToken()); // 5
        int B = Integer.parseInt(st.nextToken()); // 3
        int C = Integer.parseInt(st.nextToken()); // 2
        int M = Integer.parseInt(st.nextToken()); // 10

        // 하루에 1시간 일하면 피로도는 5만큼 쌓이고
        //                  일은 3만큼 처리할 수 있다
        //       1시간 쉰다면 피로도는 2만큼 줄어든다
        //       피로도가 10 넘게 일하면 일을 그만 두게 된다

        int fatigue = 0; // 현재 피로도
        int workDone = 0; // 총 처리한 일의 양

        for(int time = 0; time < 24; time++) {
            // 일을 할 수 있는 경우
            // => 피로도를 최대한 M을 넘지 않는단 조건을 이용
            if(fatigue + A <= M) {
                fatigue += A;
                workDone += B;
            // 쉬어야 하는 경우
            }else {
                fatigue -= C;
                if(fatigue < 0) fatigue = 0;
            }


        }
        System.out.println(workDone);

    }
}
반응형