標準9663,N-Queen-BackTracking



https://www.acmicpc.net/problem/9663
1.アイデア
BackTrackingを使用してブランチを行い、有望なノードのみをチェックします.

  • ちくじけんさぎょうれつ

  • 基本的に、皇后一行は1つしか置けません.
    =>上下直線でXを脅かす.

  • 一行で左右の列を確認し、promising放置皇后

  • Queenpromisingを配置するかどうか
    => boolean isPromising(int depth)

  • 前の行の皇后とは別の列にあります
    :col[depth]col[0]col[depth-1]の比較

  • 前の行の皇后とは異なる対角線に位置しています
    :同じ対角線上の位置=>「行の相違==列の相違」

  • 再帰終了条件:最後の行がチェックされている場合
  • 2.資料構造
  • int[] col:女王の各行の列の位置を保存
    ex)col[0]:0行のQueenの列位置col[0] = 3の場合[0][3]は、
  • に皇后を置く
    3.時間複雑度
  • backtrack+枝切りpromisingノードを1つだけチェック:O(N!)未満
    =>N最大値代入:おおよそ14!=以下87178291200
  • Brootforceを使用して、NxN内のすべてのセルを確認します.
  • 時間複雑度:O(N^N)
    =>タイムアウト!!
  • コード#コード#
    import java.io.*;
    
    public class Main_Promising {
    	static int n;						// n x n 행렬, n개 퀸 (1 ~ 14)
    	static int[] col;					// 각 행에 배치한 퀸의 열 위치
    	static int count;					// 출력: 가능한 경우의 수
    
    	static void solution(int depth) {
    		if (depth == n) {				// 마지막 행까지 확인한 경우
    			count++;
    			return;
    		}
    
    		// 한 행 확인
    		for (int i = 0; i < n; i++) {
    			col[depth] = i;				// [depth][i] 에 퀸 배치
    			if (isPromising(depth))		// 퀸 배치 후 promising 한 경우, 다음 행 탐색
    				solution(depth + 1);
    		}
    	}
    
    	/* 배치한 depth 행의 퀸이 promising 한지 판단 - 이전 윗 행들의 퀸과 비교 */
    	static boolean isPromising(int depth) {
    		for (int i = 0; i < depth; i++) {
    			if (col[i] == col[depth])			// 같은 열인지 확인
    				return false;
    			if ((depth - i) == Math.abs(col[depth] - col[i]))		// 같은 대각선 상인지 확인
    				return false;
    		}
    
    		return true;
    	}
    
    	public static void main(String[] args) throws IOException {
    		BufferedReader br = new BufferedReader(
    				new InputStreamReader(System.in)
    		);
    
    		n = Integer.parseInt(br.readLine());
    		col = new int[n];
    
    		if (n == 1) {
    			System.out.println(1);
    			return;
    		}
    		else if (n == 2) {				// n = 2 인 경우, 퀸 배치 불가
    			System.out.println(0);
    			return;
    		}
    
    		solution(0);
    		System.out.println(count);
    	}
    }