Q 13300 방 배정

💡 문제 요약 및 분석

방을 배정하는 규칙에 따라서 최소 몇 개의 방이 필요한지 구하면 된다.

  • 남학생은 남학생끼리, 여학생은 여학생끼리 같은 방이다.

  • 같은 학년의 학생들로 배정해야 한다.

  • 방의 최대 인원 수를 넘어서면 새로운 방을 배정한다.

💡 알고리즘 설계

✅ 핵심 아이디어 : int[성별][학년] 로 이차원 배열을 만들고 해당하는 인원을 추가하며 방의 수를 count 한다.

  1. 입력

    • int[][] 이차원 배열 생성.
    • 정수 N 까지 표준입력을 받는다. (StringTokenizer 사용)
  2. 연산

    • 표준 입력으로 학생 정보가 들어오면 해당하는 인덱스에 +1 한다. (예: 1 1 -> ary[1][0])
    • 이 때 조건문을 수행하여 필요한 방의 개수(count)를 누적합한다. (index > 0, index % max == 0, index == 0 세 가지 조건으로 구성)
  3. 출력

    • 누적합한 count 변수를 출력한다.

💡 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

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 N = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());
        int[][] rooms = new int[2][6];
        int count = 0;

        for (int i = 0; i < N; i++) {
            st = new StringTokenizer(br.readLine());
            int gender = Integer.parseInt(st.nextToken());
            int grade = Integer.parseInt(st.nextToken()) - 1;

            if (rooms[gender][grade] == 0 || rooms[gender][grade] % K == 0) {
                rooms[gender][grade] += 1;
                count++;
            } else {
                rooms[gender][grade] += 1;
            }
        }
        System.out.println(count);
    }
}

💡 시간 복잡도, 공간 복잡도

시간 복잡도공간 복잡도
O(n)O(1)

💡 느낀점 및 기억할 정보

  • 지역변수 활용 : rooms[i][j] 의 값을 int num 변수에 담을 때, num 은 원본 그 자체가 아닌 새로운 지역 변수로 저장된다. 그렇기 때문에 num 의 값을 아무리 변경해도 원본은 바뀌지 않는다. 이 점을 염두에 두고 구현하자 !

  • 조건문 설계 : 평소 개발할 때 조건문 설계를 잘 못하는 편인데 ㅜㅜ 이번에도 그랬다. 조건문을 어떤 식으로 구성하냐에 따라 결과가 달라지기 때문에 나의 의도와 맞지 않는 출력이 이루어진다면 조건문을 먼저 살펴봐야겠다.

🤓 System.in.read()

다른 사람의 풀이를 보다가 System.in.read() 라는 입력 방식을 사용한 것이 눈에 띄어 알아보았는데, 이것은 저수준 입력 방식의 하나로, 표준 입력(키보드 입력)을 바이트 단위로(ASCII) 직접 받아서 BufferedReader + StringTokenizer 방식보다 더 빠르다고 한다. (다만 다루기 힘든 것이 단점 !)

입력값이 많을 때는 아래와 같은 방식으로 파싱한다. 다음 문제부터 활용하면서 연습을 해봐야겠다.

static int readInt() throws Exception {
    int c, n = 0;

    // 공백, 줄바꿈 등 무시 (숫자 시작 전까지 건너뜀)
    while ((c = System.in.read()) <= 32); // ASCII 32 이하: 공백, 개행 등

    // 숫자가 나올 때까지 계속 읽어서 정수로 만들기
    do {
        n = n * 10 + (c & 15); // (c - '0')과 같음
    } while ((c = System.in.read()) > 32); // 공백 또는 줄바꿈이면 중단

    return n;
}
  • c & 15 = 한 자리 숫자만 읽을 때 쓴다. (입력값이 123일 때, 3만 남음)

  • n * 10 + (C & 15) = 누적해서 정수로 만든다. (입력값 123을 정수로 저장)