코딩테스트

자바 배열 문제 풀이 기록 (백준 1236 - 성지키기)

dev-nadan 2025. 7. 25. 11:49

1. 문제 개요

오늘은 백준 그리디 문제 중 하나인 1236번 - 성 지키기를 풀었다.
문제의 핵심은 각 행/열에 최소한 한 명의 경비원이 존재해야 성이 안전하다는 조건을 만족하도록 경비원을 최소 몇 명 배치해야 하는지를 구하는 것이다.


2. 문제 접근 방법

문제를 푸는 방법은 단순한 행/열 체크 + 최대값 선택이다.

  1. 각 행에 경비원이 있는지 체크
  2. 각 열에 경비원이 있는지 체크
  3. 경비원이 하나도 없는 행/열의 수를 각각 구하고, 이 중 더 큰 값을 출력

즉, 안전하지 않은 행/열 중 더 많은 쪽만큼 경비원을 배치하면 된다.


3. 주요 개념

행/열 체크 배열

boolean[] existRow = new boolean[N];
boolean[] existCol = new boolean[M];

 

  • existRow[i]가 true이면 i번째 행에 경비원이 있음
  • existCol[j]가 true이면 j번째 열에 경비원이 있음

입력 처리 주의 (nextLine() 버그)

Scanner를 사용할 때, nextInt() 후 바로 nextLine()으로 문자열을 읽으면 빈 줄("")을 받아오면서 입력이 밀리는 문제가 발생한다.

int N = sc.nextInt();
int M = sc.nextInt();
sc.nextLine(); // ← 개행 제거용으로 딱 1번만 필요

 

이 줄을 빼먹거나 여러 번 넣으면 런타임 에러가 발생한다.


4. 전체 코드

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int N = sc.nextInt(); // 행 수
        int M = sc.nextInt(); // 열 수
        sc.nextLine(); // 개행 제거

        char[][] map = new char[N][M];

        for (int i = 0; i < N; i++) {
            String line = sc.nextLine();
            map[i] = line.toCharArray();
        }

        boolean[] existRow = new boolean[N];
        boolean[] existCol = new boolean[M];

        // 경비원이 있는 행/열 체크
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < M; j++) {
                if (map[i][j] == 'X') {
                    existRow[i] = true;
                    existCol[j] = true;
                }
            }
        }

        int needRow = 0;
        int needCol = 0;

        for (int i = 0; i < N; i++)
            if (!existRow[i]) needRow++;

        for (int j = 0; j < M; j++)
            if (!existCol[j]) needCol++;

        System.out.println(Math.max(needRow, needCol));
    }
}

 


5. 런타임 에러 원인 분석

처음에 런타임 에러가 발생했는데, 이유는 다음과 같다:

  • nextInt()는 숫자만 읽고 개행 문자(\n)는 버리지 않음
  • 그래서 nextLine()을 넣지 않으면 첫 줄을 날려버리거나,
  • 반대로 여러 번 nextLine()을 넣으면 입력을 덜 받아서 에러 발생
sc.nextLine(); // ← 딱 1번만 써야 함

 


6. 마무리

이번 문제를 통해 행과 열을 따로 체크하고 필요한 경비원 수를 계산하는 방식, 그리고 Scanner의 입력 처리 방식에 대한 이해를 확실히 할 수 있었다.

다음부터는 nextInt() 다음에 nextLine()은 반드시 한 번만!
그리고 문자열 입력은 toCharArray()로 받으면 2차원 배열을 쉽게 만들 수 있다.