
https://www.acmicpc.net/problem/9663
Backtracking 으로 가지치기를 해가며, 유망한 노드에 대해서만 확인
행렬의 한 행씩 확인
기본적으로, 퀸은 한 행에 1 개씩만 배치 가능
=> 상하 직선 상으로 위협 X 해야하므로
한 행에서 좌 ~ 우로 열을 확인해가면서,
promising 하면 (퀸을 놓을 수 있는 경우) 퀸 배치
배치하려는 퀸의 promising 여부
=> boolean isPromising(int depth)
이전 윗 행의 퀸들과 서로 다른 열에 위치
: col[depth]와 col[0] ~ col[depth-1] 비교
이전 윗 행의 퀸들과 서로 다른 대각선 상에 위치
: 같은 대각선 상에 위치 => "행의 차이 == 열의 차이"
재귀 종료 조건: 마지막 행까지 모두 확인한 경우
int[] col: 각 행에 배치된 퀸의 열 위치 저장col[0]: 0 행에 배치된 퀸의 열 위치col[0] = 3 이면, [0][3]에 퀸 배치됨promising한 노드만 확인: O(N!) 미만브루트 포스로 N x N 의 모든 칸을 확인하는 경우
- 시간 복잡도: 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);
	}
}