백준 5597번: 과제 안 내신 분..?

레곤토르닉·2025년 8월 18일
0

BaekJoon

목록 보기
35/64
post-thumbnail

백준 5597번: 과제 안 내신 분..?

1번부터 30번까지의 학생 중 과제를 제출한 28명의 출석번호가 주어질 때, 제출하지 않은 2명의 출석번호를 찾는 문제입니다. Boolean 배열을 출석부처럼 활용하여 제출 여부를 체크하는 간단한 아이디어로 해결할 수 있습니다.


✅ 문제 개요

항목내용
문제 번호5597번 - 과제 안 내신 분..?
난이도브론즈 5
핵심 알고리즘구현, 배열

✅ 문제 설명 요약

  • 입력: 총 28줄에 걸쳐 과제를 제출한 학생 28명의 출석번호(1~30 사이의 자연수)가 주어집니다. 중복은 없습니다.
  • 출력: 제출하지 않은 2명의 출석번호를 출력합니다. 작은 번호를 먼저, 큰 번호를 나중에 출력해야 합니다.
  • 규칙:
    • 학생은 총 30명이며, 출석번호는 1번부터 30번까지입니다.
    • 정확히 2명이 과제를 제출하지 않았습니다.

✅ 풀이 전략

이 문제는 '누가 제출했는지'를 기록하고, 나중에 '제출하지 않은 사람이 누구인지'를 확인하는 문제입니다. 이러한 '체크' 과정은 배열, 특히 Boolean 배열을 사용하면 매우 효율적이고 직관적으로 해결할 수 있습니다.

1️⃣ 핵심 아이디어: 출석부 만들기

  • 30명의 학생이 과제를 냈는지 안 냈는지 상태를 기록할 '출석부'를 만듭니다.
  • 크기가 31인 boolean 배열을 선언하면, 1번부터 30번 학생을 배열의 1번부터 30번 인덱스에 각각 매칭시킬 수 있습니다.
  • boolean 배열의 값은 초기에 모두 false('안 냄')로 시작합니다.

2️⃣ 제출자 체크하기

  • 총 28개의 입력(제출한 학생의 번호)을 받습니다.
  • 입력으로 학생 번호 n이 들어오면, 우리 '출석부' 배열의 n번째 칸을 true('냄')로 바꿔줍니다.
  • submitted[n] = true;

3️⃣ 미제출자 찾기

  • 28명의 제출 기록을 모두 반영한 후, '출석부' 배열을 1번부터 30번까지 쭉 훑어봅니다.
  • 만약 submitted[i]의 값이 여전히 false라면, i번 학생은 과제를 제출하지 않은 것입니다.
  • 해당 i를 출력합니다.
  • 1번부터 순서대로 확인하기 때문에, 자연스럽게 작은 번호가 먼저 출력됩니다.

예시:
1. boolean[] submitted = new boolean[31]; 생성 (모든 값이 false)
2. 입력으로 3, 1, 4, ..., 30 (총 28개)가 들어옴
3. submitted[3] = true;, submitted[1] = true;, submitted[4] = true; ...
4. 모든 입력 처리 후, 1번부터 30번까지 for문으로 순회
5. i = 1: submitted[1]true -> 통과
6. i = 2: submitted[2]false -> 2 출력
7. i = 3: submitted[3]true -> 통과
8. ...
9. i = 5: submitted[5]false -> 5 출력
10. ... 끝까지 순회. 최종 결과는 2와 5가 오름차순으로 출력됩니다.


✅ Java 코드 예제

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

        // 1. 출석부(boolean 배열) 생성
        // 1번부터 30번까지 사용하기 위해 크기를 31로 설정
        boolean[] submitted = new boolean[31];

        // 2. 제출한 28명의 번호를 입력받아 체크
        for (int i = 0; i < 28; i++) {
            int n = Integer.parseInt(br.readLine());
            submitted[n] = true;
        }

        // 3. 1번부터 30번까지 순회하며 미제출자(false) 찾기
        for (int i = 1; i <= 30; i++) {
            if (!submitted[i]) {
                bw.write(String.valueOf(i));
                bw.newLine();
            }
        }

        bw.flush();
        bw.close();
        br.close();
    }
}

⚠️ 실전 주의사항

항목설명
배열 인덱스배열의 크기를 30이 아닌 31로 선언하면, 0번 인덱스를 무시하고 출석번호 1~30을 인덱스 1~30에 바로 매칭시킬 수 있어 코드가 매우 직관적이 됩니다.
입력 개수입력이 28개로 고정되어 있으므로, for 반복문을 28번 실행하여 입력을 받으면 됩니다.
출력 형식두 명의 번호를 오름차순으로, 한 줄에 하나씩 출력해야 합니다. System.out.println()을 사용하거나 bw.newLine()을 추가해야 합니다.
다른 풀이ArrayList에 1~30을 모두 넣고, 입력받은 숫자를 remove() 하는 방식도 가능하지만, boolean 배열을 이용한 체크 방식이 더 간단하고 메모리 효율도 좋습니다.

📝 마무리 요약

✔️ '존재 여부'나 '체크 여부'를 확인하는 문제는 boolean 배열을 활용하는 것이 매우 효과적입니다.
✔️ 배열의 인덱스를 문제의 번호(출석번호)와 일치시키면 코드가 직관적이고 간단해집니다.
✔️ 풀이 순서: 1. boolean 배열 생성 -> 2. 입력받은 번호의 인덱스를 true로 변경 -> 3. 배열을 순회하며 false인 인덱스 출력.
✔️ 이 패턴은 빠진 숫자나 중복된 숫자를 찾는 다양한 문제에 널리 응용할 수 있습니다.

profile
기록은 나의 무기, 원칙은 나의 방패

0개의 댓글