https://www.acmicpc.net/problem/9663
N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다.
N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.
const find = (row: number, col: number, visited: number[][]) => {
if (visited[row][col] === 1 || visited[row][col] === 2) {
// cnt++;
return;
}
visited[row][col] = 1;
for (let i=0; i<N; i++) {
for (let j=0; j<N; j++) {
for (let k=0; k<pos.length; k++) {
const x = pos[k][0] + i;
const y = pos[k][1] + j;
// 배열의 영역을 벗어나지 않을 경우
// 퀸의 이동 범위를 모두 true로 체크해줌
if ( x >= 0 && x < N
&& y >= 0 && y < N
) {
find( y, x, visited);
}
}
}
}
}
해당 퀸이 도달할 수 없는 장소까지 true로 표기한다. 다른방법이 필요하다
const N = +input();
const board = Array.from(
{length: N}, () =>
Array.from({length: N}, () => 0)
);
let cnt = 0;
const find = (beforeCol: number, canPutQueen: boolean[]) => {
if (canPutQueen.every(val => val === false)) cnt++;
for (let i=0; i<N; i++) {
for (let j=0; j<N; j++) {
// 만약 이전 row의 -1, 1, +1이 아닐 때
// && 해당 col이 queen을 놓을 수 있는 위치인 경우
if ( !(j >= beforeCol - 1 && j <= beforeCol + 1) && (canPutQueen[j] )
) {
canPutQueen[j] = false;
find( j, canPutQueen);
}
}
}
}
for (let i = 0; i < N-1; i++) {
const canPutQueen = Array(N).fill(true);
for (let j=0; j<N; j++) {
canPutQueen[j] = false;
find(j, canPutQueen);
}
}
console.log(cnt);
const N = +input();
// 가로로 놓을수 있는지 확인
const canPutCol = Array(N).fill(true);
// 왼쪽아래 -> 오른쪽 위 대각선 놓을 수 있는지 확인
const rightUp = Array(N*2).fill(true);
// 왼쪽위 -> 오른쪽 아래 대각선 놓을 수 있는지 확인
const rightDown = Array(N*2).fill(true);
let cnt = 0;
const find = (row: number) => {
if (row === N) {
cnt ++;
return;
}
for (let col=0; col<N; col++) {
if ( canPutCol[col]
&& rightUp[row - col + N]
&& rightDown[row+col]
){
canPutCol[col] = false;
rightUp[row - col + N] = false;
rightDown[row + col] = false;
find( row + 1);
canPutCol[col] = true;
rightUp[row - col + N] = true;
rightDown[row + col] = true;
}
}
}
find(0);
console.log(cnt);
풀이 방법을 계속 바꾼 끝에 드디어 성공했다.
기존에 for문을 재귀 바깥에서 한번, 안에서 한번 중복돼서 계속 돌리는게 아니라고 생각했다.
앞서 푼 N, M 문제를 생각해보니 굳이 밖에서 돌릴 필요가 없었다.
어차피 N개의 줄을 내려가면서 돌아갈거니까!!!
생각보다 푸는데 시간이 오래 걸린 문제다.
하지만 문제를 풀면서 백트래킹이 정확히 어떤식의 알고리즘인지 이해가 됐다.
앞으로 비슷한 문제가 나오면 바로 풀어버릴 자신감이 생겨났다!!!