• Feed
  • Explore
  • Ranking
/
/
    백준

    백준 9663: N-Queen(Python, 파이썬, Backtracking, 백트래킹)

    백준9663
    밤
    밤톨이형아
    2025.11.16
    ·
    4 min read

    8332

    Pypy로 제출했습니다.

    문제

    N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다.

    N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.

    입력

    첫째 줄에 N이 주어진다. (1 ≤ N < 15)

    출력

    첫째 줄에 퀸 N개를 서로 공격할 수 없게 놓는 경우의 수를 출력한다.

    문제풀이

    1.N*N 크기의 체스판이 있다.

    단, N x N 크기의 배열을 선언하지않고,

    N 크기의 리스트를 선언한다. board = [-1] * N -> 이 리스트는 뭘 의미하냐?

    board[i] = 3 이라고 해보자. -> i번째 행에는 3번째 열에 퀸이 존재한다. 를 의미한다.

    2.지금 행에서 퀸을 놓을 수 있는 자리를 탐색한다.

    for col in range(N): #지금 row는 고정됐다. col을 한 칸씩 움직여가면서 퀸을 놓을 수 있는지 확인할 것이다.

        for col in range(N):
            if used_col[col]:  # 이미 사용한 열이면 skip
                continue
    
            board[row] = col  # row행 col열에 퀸 배치
    
            if safe(row):  # 충돌 없을 때만 다음 행 진행
                used_col[col] = True
                back_tracking(row + 1)
                used_col[col] = False  # 백트래킹
    

    우선 현재 board[row] = col을 해서, 퀸을 놓아보자.

    그리고 safe(row)를 호출해서, 다른 퀸들과 겹치는지 보면 될 것이다.

    만약에 safe함수에서 True를 리턴받으면, board[row] = col은 퀸을 놓을 수 있는 유효한 자리임을 의미한다.

    이제 col은 더이상 퀸을 놓을 수 없다. -> used_col[col] = True 로 처리.

    
    def safe(row) -> bool:  # row행에 놓은 퀸이 안전한지 확인
        for r in range(row):
            # board[row] = 현재 row에 놓은 col
            # board[r]   = r행에 놓인 col
            if board[row] == board[r]:  # 같은 열
                return False
            if abs(board[row] - board[r]) == (row - r):  # 같은 대각선
                return False
        return True

    정답 코드

    import sys
    
    def safe(row) -> bool:  # row행에 놓은 퀸이 안전한지 확인
        for r in range(row):
            # board[row] = 현재 row에 놓은 col
            # board[r]   = r행에 놓인 col
            if board[row] == board[r]:  # 같은 열
                return False
            if abs(board[row] - board[r]) == (row - r):  # 같은 대각선
                return False
        return True
    
    
    def back_tracking(row):
        global count, N
    
        # row == N이면 모든 행에 퀸을 성공적으로 놓은 상태
        if row == N:
            count += 1
            return
    
        for col in range(N):
            if used_col[col]:  # 이미 사용한 열이면 skip
                continue
    
            board[row] = col  # row행 col열에 퀸 배치
    
            if safe(row):  # 충돌 없을 때만 다음 행 진행
                used_col[col] = True
                back_tracking(row + 1)
                used_col[col] = False  # 백트래킹
    
            # 충돌이면 자연스럽게 next col
    
    # 입력 처리
    N = int(sys.stdin.readline().strip())
    board = [-1] * N         # board[row] = col
    used_col = [False] * N   # 열 체크
    count = 0
    
    # 실행
    back_tracking(0)
    print(count)
    







    - 컬렉션 아티클