https://www.acmicpc.net/problem/9663
접근 방법
1차원 배열을 만들어 행은 인덱스에 열은 해당 행의 번째에 배열의 값으로 들어가게 하였다.
(예를 들어, 1행 3열이면 positoins[1] = 3)
백트래킹 알고리즘을 통해 1 -> N행으로 depth를 넘어가면서 조건을 통과하는 경우 다음 깊이로 재귀하도록 구현했다.
다음 깊이로 재귀하는 조건과 구현 방법은 다음과 같다
1. 이미 같은 열에 퀸이 놓여있지 않은 경우
-> 열을 나타내는 것은 1차 배열의 값이다. 따라서 이전까지의 배열 인덱스를 탐색하면서 값이 존재하지 않으면 조건에 부합하다. 즉, position[i] != number
2. 이미 놓여있는 퀸이 대각선에 있지 않은 경우
-> 대각선에 놓여있는 경우의 기울기는 |1|임을 이용한다. |y2 - y1 / x2 - x1| = 1이기 때문에 |y2 - y1| != |x2 - x1|인 경우 조건에 부합하다.
재귀 함수의 끝은 depth == N, 다시 말해 (중간에 하나라도 조건에 맞지 않으면 돌아가는 백트래킹 덕분에) N번째 위치까지 모두 탐색한 경우에는 경우의 수++ 가능하다.
최종 코드
import java.util.Scanner;
public class Main {
private static int count;
private static int N;
private static int[] positions;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
N = scanner.nextInt();
count = 0;
for (int i = 1; i <= N; i++) {
positions = new int[16];
positions[1] = i;
dfs(1);
}
System.out.println(count);
}
private static void dfs(int depth) {
if (depth == N) {
count++;
} else {
for (int i = 1; i <= N; i++) {
if (isPossible(i, depth + 1)) {
positions[depth + 1] = i;
dfs(depth + 1);
}
}
}
}
private static boolean isPossible(int number, int depth) {
for (int i = 1; i < depth; i++) {
if (positions[i] == number) {
return false;
}
if (Math.abs(positions[i] - number) == Math.abs(i - depth)) {
return false;
}
}
return true;
}
}
반응형
'Tech > Problem Solving' 카테고리의 다른 글
[백준 2609] 최대공약수와 최대공배수 (Java) (0) | 2020.02.07 |
---|---|
[백준 1978] 소수 찾기 (Java) (0) | 2020.02.06 |
[백준 1182] 부분수열의 합 (Java) (0) | 2020.01.30 |
[백준 5430] AC (Java) (0) | 2020.01.27 |
[백준 1966] 프린터 큐 (Java) (0) | 2020.01.22 |