즉, 백트래킹은 트리 구조를 기반으로 DFS로 깊이 우선 탐색을 진행하면서 각 루트에 대해서 조건이 부합하는지 Promissing(유망한지) 보고, 만약 해당 트리에서 조건에 맞지않는 노드는 더이상 DFS로 탐색하지 않고, 가지를 쳐낸다(Pruning)
대표적인 백트래킹 문제로 N*N 크기의 체스판에 N개의 퀸을 서로 공격할 수 없도록 배치하는 문제
퀸은 수직, 수평, 대각선 방향으로 이동(공격)이 가능하다
수직체크 & 대각선 체크를 진행한다 (수평체크는 어짜피 한 행에 하나만 놓으면되므로 검사하지 않는다)
수직체크
대각선 체크
public class N_Queens {
static int[] result;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] Ns = br.readLine().split(" ");
int N = Integer.parseInt(Ns[0]);
// 모든 행을 채운 결과
result = new int[N];
//각 행을 채운 결과를 담는곳
List<Integer> current_candidate = new ArrayList<>();
DFS(N, 0, current_candidate);
}
private static void DFS(int N, int current_row, List<Integer> current_candidate) {
if (current_row == N){
for (int i = 0; i < current_candidate.size(); i++){
result[i] = current_candidate.get(i);
}
Arrays.stream(result).forEach(s -> System.out.print(s+" "));
System.out.println();
}
else {
for (int current_col = 0; current_col < N; current_col++){
if (is_available(current_candidate, current_col)){
current_candidate.add(current_col);
DFS(N, current_row + 1, current_candidate);
//조건에 부합되지 않거나 N개를 모두 채운 경우 하나씩 빼주면서 backTracking해준다
current_candidate.remove(current_candidate.size() - 1);
}
}
}
}
private static boolean is_available(List<Integer> candidate, int current_col) {
int current_row = candidate.size();
for (int queen_row = 0; queen_row < current_row; queen_row++){
if (candidate.get(queen_row) == current_col
|| Math.abs(candidate.get(queen_row) - current_col) == current_row - queen_row){
return false;
}
}
return true;
}
}