백준 자바 9663 N-Queen

김재동·2024년 7월 9일
0

문제

목록 보기
3/16

..백트래킹이라는 개념을 이번 강의를 통해 처음 접했는데,
나랑 안맞는 것 같다 ㅎ..

우선 이 문제는 이번 주의 강의였던
[바킹독의 실전 알고리즘] 0x0C강 - 백트래킹
에 있던 예제 중 하나였다.
물론 강의는 c++로 되어있으나, 우리는 자바로 문제를 풀기에
강의 내용을 이해한 후 자바로 재해석하여 문제를 해결하였다.

package test11;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Ox11_Q3_1 {
	static int cnt = 0; // 경우의 수
	static int n; 
	static boolean issued1 [] = new boolean [30]; // 세로 열 체크
	static boolean issued2 [] = new boolean [30]; // 오른쪽 위 대각선 체크
	static boolean issued3 [] = new boolean [30]; // 오른쪽 아래 대각선 체크
	// 백준 9663 G4 N-Queen
	public static void main(String args []) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		n = Integer.parseInt(br.readLine());
		checkFunc(0);
		System.out.println(cnt);

	}
	
	public static void checkFunc(int cur) {
		// 체스 놓은 말 개수가 n이랑 같으면 return 
		if (cur == n) {
			cnt++;
			return;
		}
		for (int i = 0; i < n; i++) {
			// Q가 있는 열, 오른쪽 대각선, 왼쪽 대각선에 값이 있는 경우 continue;
			if (issued1[i] || issued2[i + cur] || issued3[cur - i + n - 1]) {
				continue;
			}
			// 세 곳 값 세팅
			issued1[i] = true;
			issued2[i + cur] = true;
			issued3[cur - i + n - 1] = true;
			// 재귀
			checkFunc(cur + 1);
			// 다 놓아본 후 새로 복원
			issued1[i] = false;
			issued2[i + cur] = false;
			issued3[cur - i + n - 1] = false;
		} // for fin
		
	}
}

처음에 예제를 볼때, 왜 1차월 배열로 값을 체크하지? 하는 생각이 들었다.
제대로 이해가 되지 않았었으나, 구글링을 통해 해당 개념을 어느정도 이해할 수 있었다.
문제 특성상 체스를 한 개 두면 해당 열과 행 모두 둘 수 없기에 위에서 보면 하나의 열에 하나씩
값이 들어가 있는 느낌이다. 즉 배열 한 개가 있을 때 해당 인덱스가 열이고, 그 안에 있는 각각의 값이 행을 의미한다고
해석하면 된다.

다음으로, 함수 checkFunc를 해석해 보겠다. 체스를 말을 놓은 개수 cnt를 인자로 받고있다.
만약 (0,0) 에 퀸을 둔다고 가정하면 이에 해당 하는 x열, x행, 대각선 방향은 모두 값을 놓을 수 없으므로
이를 손쉽게 체크하기 위해 배열 세개를 두어 간편하게 검증하였다.
이후 해당 x열 (인덱스)를 의미하는 isuued1
해당 x열의 오른쪽 대각선 증가 를 의미하는 issued2
해당 x열의 왼쪽 대각선 감소를 의미하는 isuued3 에 각각 true값을 준 후 반복하여 해당 경우의 수를 구해고,
만약 재귀문이 종료되면 해당 구문들을 다시 false로 초기화해준다.

문제 자체는 어려웠으나, 강의 덕분에 차근차근 따라하여 수월하게 해결하긴했다.
하지만, 앞으론 혼자서도 해결할 수 있어야하므로 이에 방심하지 않고 꾸준히 공부해야겠다.

profile
성장중

0개의 댓글