[백준/JAVA] 22864번 : 피로도
https://www.acmicpc.net/problem/22864
📌 문제 요약
하루 24시간 동안 1시간 단위로 일을 하거나 쉴 수 있으며, 일할 때는 피로도가 증가하고 처리량이 늘어납니다. 피로도가 최대치인 M을 초과하지 않도록 하면서 최대한 많은 일을 처리하는 것이 목표입니다.
- 일을 할 때: 피로도가 A만큼 증가하고, 처리량은 B만큼 증가.
- 쉴 때: 피로도가 C만큼 감소하고, 처리량에는 변화가 없음.
- 피로도가 0 이하가 되면 0으로 유지됨.
- 하루는 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);
}
}