[프로그래머스] Lv1.택배 상자 꺼내기.java.
<링크>
https://school.programmers.co.kr/learn/courses/30/lessons/389478
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
<문제 설명>
1~n의 번호가 있는 택배 상자가 창고에 있다.
당신은 택배를 정리 중이다.
왼쪽에서 오른쪽으로 가면서 1번 상자부터 번호 순서대로 한개씩 놓는다.
가로로 택배를 w개 놓았다면 이번에는 오른쪽에서 왼쪽 방향으로 그 위층에 한개씩 쌓는다.
그 층에 다시 w개를 놓았다면 이를 반복한다. 이러한 방식으로 n개 상자를 쌓는다.
택배 상자 A번을 꺼내려면 그 위의 상자를 모두 꺼내야합니다.
1번을 꺼내려면 12, 13번 상자를 꺼내야합니다.
당신이 꺼내려는 상자 번호가 주어질 때, 꺼내려는 상자를 포함하여
총 몇개의 상자를 꺼내야 하는지 알고 싶다. 이 때,
- 창고에 있는 택배 상자의 개수 n, (2<= n <= 100)
- 가로로 놓는 상자의 개수 w, (1<= w <= 10)
- 택배 상자의 번호를 나타내는 정수 num, (1<= num <= n)
<문제 해석>
1. 왼쪽으로만 쌓는 것이 아니고, 왼쪽 오른쪽 번갈아가며 쌓아간다.
2. 그렇다면 홀수라인은 왼쪽, 짝수라인은 오른쪽으로 쌓아오를 것이다.
3. 마지막 라인의 택배상자 갯수는 n%w 이거나 n%w ==0일 경우 w개,
해당 라인 레벨은 n/w의 몫 +1 으로 생각했으나, n=6, w=6일 경우 2를 출력한다.
0-Based로 level = (num - 1) / w + 1 로 풀자.
4. answer은 꺼내려는 상자를 포함한 꺼내야하는 상자의 총 개수
5. num번째 박스 포함이므로 1 + (마지막 라인 층수 - 현재 라인 층수) 를 계산하고,
마지막 라인의 박스 수와 방향을 생각해서 -1 해주면 되겠다.
이제 풀어보자.
<문제 풀이>
class Solution {
public int solution(int n, int w, int num) {
// 1. num번 상자가 속한 라인 계산 (1-based)
int numLine = (num - 1) / w + 1; // num이 속한 라인의 번호
// 2. 전체 라인 수 계산
int totalLines = (n + w - 1) / w; // 전체 라인 수
// 3. 마지막 라인 박스 개수 계산
int lastLineBoxes = n % w == 0 ? w : n % w;
// 4. num번 상자가 속한 라인과 마지막 라인의 관계만 고려
// 현재 라인부터 마지막 라인까지 꺼내야 하는 상자 개수 계산
int answer = 1; // 현재 num 상자 포함
// num번 상자 속한 라인과 마지막 라인의 관계에 따른 계산
if (numLine == totalLines) { // num이 마지막 라인에 있을 경우.
return answer;
}
else{ // num이 마지막이 아닌 경우
int numIndex = (num - 1) % w + 1;
// 1. totalLines -numLine 가 홀수일 경우(서로 방향이 다름)
if((totalLines - numLine) %2 ==1){
// 서로 방향이 다르므로 numIndex + lastLineBoxes가 w보다 작거나 같은 경우
// 해당 인덱스에서 마지막 라인의 박스 개수가 채워지지 않음.
if(numIndex + lastLineBoxes <= w){
answer += (totalLines - numLine) - 1;
}
// 큰 경우
else{
answer += (totalLines - numLine);
}
}
else{
// 2. totalLines -numLine 가 짝수일 경우(방향 같음)
// numIndex가 lastLineBoxes보다 작거나 같을 경우
if(numIndex <= lastLineBoxes){
answer += (totalLines - numLine);
}
else answer += (totalLines - numLine) -1;
}
}
return answer;
}
}