N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다.
N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.
첫째 줄에 N이 주어진다. (1 ≤ N < 15)
첫째 줄에 퀸 N개를 서로 공격할 수 없게 놓는 경우의 수를 출력한다.
checkAttackablePos(x, y) 는 퀸이 (x, y) 지점에 놓였을 때 공격가능한 지점을 boolean 타입의 canAttack 배열에 표시하는 함수이다.x 보다 큰 행에만(방금 놓은 퀸보다 아래쪽 영역) 표시를 할 것이다.dfs(k) 메서드k가 n이 되면 cnt++하며 탈출하는 재귀함수이다.k 번째줄을 돌며 canAttack 배열이 false인 부분에 퀸을 놓고(board[k][i] = 1) 공격 범위를 표시한다. 그리고 dfs(k + 1)을 호출하며 다음줄로 넘어간다.board[k][i] = 0으로 방금 놓은 퀸을 빼고for문을 이용해 canAttack 배열을 초기화 한 후for문을 이용해 남은 퀸들에 대해 공격범위를 다시 표시해준다.import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Baekjoon_9663 {
static int n;
static int[][] board;
static boolean[][] canAttack;
static int cnt = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
board = new int[n][n];
canAttack = new boolean[n][n];
dfs(0);
System.out.println(cnt);
}
public static void dfs(int k){
if(k == n){
cnt++;
return;
}
for (int i = 0; i < n; i++) {
if(!canAttack[k][i]){
canAttack[k][i] = true;
board[k][i] = 1;
checkAttackablePos(k,i);
dfs(k + 1);
// 방금 놓은 퀸 빼기
board[k][i] = 0;
// canAttack 배열 초기화
for (int j = 0; j < n; j++) {
for (int l = 0; l < n; l++) {
canAttack[j][l] = false;
}
}
// 남은 퀸들의 공격범위 표시
for (int j = 0; j < n; j++) {
for (int l = 0; l < n; l++) {
if(board[j][l] == 1){
checkAttackablePos(j, l);
}
}
}
}
}
}
public static void checkAttackablePos(int x, int y){
// 퀸의 공격범위 표시
// 아래범위
for (int i = x; i < n; i++) {
canAttack[i][y] = true;
}
int posX = x;
int posY = y;
// 대각선 왼쪽 범위
while(true) {
if(posX < 0 || posY < 0 || posX >= n || posY >= n){
break;
}
canAttack[posX++][posY--] = true;
}
// 대각선 오른쪽 범위
while(true){
if(x < 0 || y < 0 || x >= n || y >= n){
break;
}
canAttack[x++][y++] = true;
}
}
}
이 문제를 푸는 도중 메모리에 관해 궁금증이 생겨서 자바의 메모리와 GC에 대해 공부를 해봤다.