
문제 설명
- NxN 체스판에 N개의 퀸을 놓는 경우의 수를 구하는 문제입니다.
접근법
- N의 값이 14까지 가능하기 때문에 완전탐색의 경우 시간초과가 납니다.
- 가능한 총 경우의 수 -> n∗nCn
- 백트래킹을 통해 불가능한 경우의 수를 제거하는 방향으로 문제를 풀어야 합니다.
- 실제 경우의 수와 유사한 방법은 2차원 배열이지만, 퀸은 같은 행 또는 같은 열에 존재할 수 없습니다. 이를 이용해 1차원 배열에서 가능 여부를 체크할 수 있습니다.
- 1차원 배열에 나타냈지만 대각선을 판별하기 위해 퀸들의
x좌표값과 y좌표값을 모두 알고 있어야 합니다.
- 저는 배열의 인덱스를 col, 배열의 값을 row로 두었습니다.
- 이를 통해 1차원 배열에서 x좌표와 y좌표를 모두 표현할 수 있게 되었습니다.
- 체스의 좌표를 (0,0)부터 시작하게 되면 배열에 있는 0이
좌표값 0인지 초기값 0인지 구별할 수 없습니다. 그래서 N+1크기의 배열을 만들었습니다.
- array[3] = 8은 (8,3)에 퀸을 두겠다는 의미입니다.
d[r] = c 혹은 d[c] = r를 계속 생각하는 게 핵심입니다.
- 자세한 설명은 코드에 주석과 함께 진행하겠습니다.
정답
import java.util.*;
public class Main {
static int[] array;
static int N;
static int cnt;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
array = new int[N+1];
cnt = 0;
BackT(1);
System.out.println(cnt);
}
public static void BackT(int c) {
if(c > N) {
cnt++;
return;
}
for (int i = 1; i <= N; i++) {
if(!validate(i,c)) continue;
array[c] = i;
BackT(c+1);
}
}
public static boolean validate(int i,int c) {
for (int j = 1; j < c; j++) {
if( array[j] == i || Math.abs(array[j]-i) == Math.abs(j-c) ) {
return false;
}
}
return true;
}
}
기타
틀린 이유
- 접근법 자체를 잘 떠올리지 못했습니다.
- 배열의 길이를 N으로 두고 (0,0)부터 시작해 틀렸었습니다.
- 각 변수(r,c,i,...)들이 무엇을 의미하는지가 헷갈려 문제를 푸는데 오랜 시간이 걸렸습니다.