[Programmers] 체육복 - JAVA

ONE·2022년 1월 5일
0

Programmers

목록 보기
1/24

📚 Problem

체육복

  • 번호는 체격순 (1 ~ N)
  • 바로 앞 or 바로 뒤 만 빌려주기 가능
  • 여벌이 있는 학생만 체육복을 도난당한(체육복이 없는) 학생에게 빌려주기 가능
  • 여벌이 있는 학생도 도난을 당할 수 있고, 이때는 여벌이 없어져 다른 학생에게 빌려줄 수 없음
  • 체육수업을 들을 수 있는 학생의 최댓값 구하기

📝 Solution

  • 3가지의 상태로 학생들을 구분합니다
    - -1 : 체육복을 도난당해 없는 상태
    - 0 : 체육복을 본인의 것만 가지고 있는 상태 (여별 X)
    - 1 : 체육복을 여벌로 가지고 있는 상태 (2개)
  • 학생 수와 같은 int 배열을 생성합니다 (체육복의 수를 나타내는 배열, 처음엔 모두 0 으로 초기화)
  • reserve 에 있는 번호들에 해당하는 학생들의 체육복수를 1 증가시킵니다
  • lost 에 있는 번호들에 해당하는 학생들의 체육복수를 1 감소시킵니다
  • 체육복이 없는 학생들의 앞, 뒤를 조사하여 앞 또는 뒤에 체육복이 여벌로 있는 학생이 있다면 빌립니다
  • 체육복이 없는 학생들을 제외한 학생들의 수를 카운팅한 것이 결과입니다!
    public int solution(int n, int[] lost, int[] reserve){
        int answer = 0;
        int[] students = new int[n + 1];

        reserveStd(students, reserve);
        lostStd(students, lost);
        borrow(n, students);

        answer = countResult(n, students);

        return answer;
    }

💻 Code

Solution.java

public class Solution {
    public int solution(int n, int[] lost, int[] reserve){
        int answer = 0;
        int[] students = new int[n + 1];

        reserveStd(students, reserve);
        lostStd(students, lost);
        borrow(n, students);

        answer = countResult(n, students);

        return answer;
    }

    private void reserveStd(int[] students, int[] reserve){
        for(int reserveStd : reserve)
            students[reserveStd]++;
    }

    private void lostStd(int[] students, int[] lost){
        for(int lostStd : lost)
            students[lostStd]--;
    }

    private boolean isReserve(int suit){
        return suit > 0;
    }

    private boolean isNoSuit(int suit){
        return suit < 0;
    }

    private boolean withinRange(int n, int student){
        return student >= 1 && student <= n;
    }

    private void borrowFromFront(int i, int[] students){
        students[i]++;
        students[i - 1]--;
    }

    private void borrowFromBack(int i, int[] students){
        students[i]++;
        students[i + 1]--;
    }

    private boolean isFrontReserve(int n, int i, int[] students){
        return withinRange(n, i - 1) && isReserve(students[i - 1]);
    }

    private boolean isBackReserve(int n, int i, int[] students){
        return withinRange(n, i + 1) && isReserve(students[i + 1]);
    }

    private void borrow(int n, int[] students){
        for(int i = 1; i <= n; i++)
            if(isNoSuit(students[i])){
                if(isFrontReserve(n, i, students))
                    borrowFromFront(i, students);
                else if(isBackReserve(n, i, students))
                    borrowFromBack(i, students);
            }
    }

    private boolean haveSuit(int student){
        return student >= 0;
    }

    private int countResult(int n, int[] students){
        int result = 0;
        for(int i = 1; i <= n; i++)
            if(haveSuit(students[i]))
                result++;
        return result;
    }
}

SolutionTest.java

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

public class SolutionTest {
    Solution sol;

    @BeforeEach
    public void setSol(){
        sol = new Solution();
    }

    @Test
    public void solution_1(){
        assertEquals(5, sol.solution(5, new int[]{2, 4}, new int[]{1, 3, 5}));
    }

    @Test
    public void solution_2(){
        assertEquals(4, sol.solution(5, new int[]{2, 4}, new int[]{3}));
    }

    @Test
    public void solution_3(){
        assertEquals(2, sol.solution(3, new int[]{3}, new int[]{1}));
    }
}
profile
New, Strange, Want to try

0개의 댓글