• Feed
  • Explore
  • Ranking
/
/
    Problem Solving

    [Baekjoon] 비숍

    비숍_1799 [플레티넘5]
    BackTrackingDFS백준
    h
    hyeonZIP
    2026.01.21
    ·
    4 min read

    https://www.acmicpc.net/problem/1799

    import java.io.*;
    import java.util.*;
    
    public class Main {
        private static final int PLACEABLE = 1;
        private static boolean[] topLeftCross;
        private static boolean[] topRightCross;
        private static int answer, white, black;
        private static int chessBoardSize;
        private static int[][] chessBoard;
    
        public static void main(String[] args) throws IOException {
            init();
            sol();
            print();
        }
    
        private static void sol() {
            dfsWhiteTile(0, 0, 0);
            dfsBlackTile(0, 1, 0);
    
            answer = white + black;
        }
    
        private static void dfsWhiteTile(int y, int x, int bishopCount) {
            if (y >= chessBoardSize) {
                white = Math.max(white, bishopCount);
                return;
            }
    
            if (x >= chessBoardSize) {
                dfsWhiteTile(y + 1, (y + 1) % 2 == 0 ? 0 : 1, bishopCount);
                return;
            }
    
            if (chessBoard[y][x] == PLACEABLE && !topLeftCross[y + x] && !topRightCross[y - x + chessBoardSize - 1]) {
                topLeftCross[y + x] = true;
                topRightCross[y - x + chessBoardSize - 1] = true;
    
                dfsWhiteTile(y, x + 2, bishopCount + 1);
    
                topLeftCross[y + x] = false;
                topRightCross[y - x + chessBoardSize - 1] = false;
            }
    
            dfsWhiteTile(y, x + 2, bishopCount);
        }
    
        private static void dfsBlackTile(int y, int x, int bishopCount) {
            if (y >= chessBoardSize) {
                black = Math.max(black, bishopCount);
                return;
            }
    
            if (x >= chessBoardSize) {
                dfsBlackTile(y + 1, (y + 1) % 2 == 0 ? 1 : 0, bishopCount);
                return;
            }
    
            if (chessBoard[y][x] == PLACEABLE && !topLeftCross[y + x] && !topRightCross[y - x + chessBoardSize - 1]) {
                topLeftCross[y + x] = true;
                topRightCross[y - x + chessBoardSize - 1] = true;
    
                dfsBlackTile(y, x + 2, bishopCount + 1);
    
                topLeftCross[y + x] = false;
                topRightCross[y - x + chessBoardSize - 1] = false;
            }
    
            dfsBlackTile(y, x + 2, bishopCount);
        }
    
        private static void init() throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            chessBoardSize = Integer.parseInt(br.readLine());
    
            chessBoard = new int[chessBoardSize][chessBoardSize];
    
            StringTokenizer st;
    
            for (int i = 0; i < chessBoardSize; i++) {
    
                st = new StringTokenizer(br.readLine());
    
                for (int j = 0; j < chessBoardSize; j++) {
                    chessBoard[i][j] = Integer.parseInt(st.nextToken());
                }
            }
    
            topLeftCross = new boolean[chessBoardSize * 2];
            topRightCross = new boolean[chessBoardSize * 2];
        }
    
        private static void print() throws IOException {
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
            bw.write(String.valueOf(answer));
            bw.close();
        }
    }

    주요 개념

    • 백트래킹

    • DFS

    • N-Queen

    풀이 방법

    8711
    • 아주 건전하게(?) 풀었다.

    • 흔한 백트래킹 문제같이 새로운 2차원 배열을 생성하고 DFS로 반복해서 메모리 초과를 달성했다.

    • N-Queen 문제를 생각해서 대각선 방문 배열을 사용하여 메모리 초과 대신 시간 초과를 달성했다.

      • N-Queen은 대각선, 가로, 세로를 제한하기 때문에 배치할 수 있는 경우의 수가 비숍보다 적어 동일한 로직을 적용할 시 시간초과가 발생한다.

      • 문제에서 제공하는 그림을 생각하지 말고 실제 체스판의 모습을 떠올려본다.

        • 실제 체스판에는 흰색과 검은색 타일이 바둑판 모양으로 되어있다.

        • 검은색 타일에 있는 비숍은 무슨일이 있어도 하얀색 타일에 있는 비숍을 공격할 수 없다.

          • 따라서 검은색 타일 DFS와 하얀색 타일 DFS의 결과가 독립적일 수 있게 된다.

          • Y좌표값의 짝수/홀수에 따라서 좌표 이동만 유의하면 DFS 로직은 동일하다.







    - 컬렉션 아티클