반응형
은세고화
뚜렷한 기억보단 흐릿한 잉크를
은세고화
전체 방문자
오늘
어제
  • 분류 전체보기 (96)
    • TDD (2)
      • 학점 산출 프로그램 (2)
    • IT (44)
      • 부스트코스 (18)
      • CS50 (3)
      • 도서추천 알고리즘 (2)
      • 스터디 일정 (3)
      • 스프링 (3)
      • 프로젝트 개발 중 발생한 에러 (8)
      • 웹개발 (4)
      • DB (3)
    • 독서 후기 (12)
      • 도서 (12)
    • e북 (3)
    • 알고리즘 (26)
    • 프로젝트 (6)
      • 향수 (6)
    • 회고 (1)

블로그 메뉴

  • 홈

공지사항

인기 글

티스토리

hELLO · Designed By 정상우.
글쓰기 / 관리자
은세고화

뚜렷한 기억보단 흐릿한 잉크를

알고리즘

백준 9663 N-Queen 자바

2022. 3. 17. 07:46
반응형

https://www.acmicpc.net/problem/9663

 

9663번: N-Queen

N-Queen 문제는 크기가 N × N인 체스판 위에 퀸 N개를 서로 공격할 수 없게 놓는 문제이다. N이 주어졌을 때, 퀸을 놓는 방법의 수를 구하는 프로그램을 작성하시오.

www.acmicpc.net

 

못 풀어서 답을 봤다. 코드는 간단하지만 생각하기 쉽지 않은 문제다.

 

 

접근 방식

단순하게 2차원 배열을 생성하고 모든 경우의 수를 계산하려고 했다. 퀸을 놓은 후 재귀 탐색을 설정하는데 어려움을 겪었었다. 정답을 보고 이해한 뒤에 며칠 뒤 다시 풀어보니 잘 풀렸다.

 

 

퀸을 놓을 수 있는지 확인할 때는 1차원 배열이면 충분하다. 가로와 세로 같은 열에 퀸을 놓을 수 없으니 1차원 배열에 row값을 삽입하고 다음 번 놓을 퀸이 이전의 row값들과 같은 값이 있다면 false를 리턴한다.

대각선의 경우 따로 공식이 있다. 

 

rowNo-i == Math.abs(col[rowNo] - col [i])

 

그림을 그려서 이해하면 공식이 이해가 간다. 

 

 

for문을 처음부터 탐색해서 1차원 배열에 i값을 삽입한다. 다음번 퀸을 놓을 수 있는지 isAvailable함수로 체크하고 놓을 수 있다면 다음 번 퀸을 재귀 탐색한다. 중간에 return된다면 다음 row에 값을 넣고 다시 재귀탐색한다.

 

배열에 값은 {1,3,5,2,6,7,8} 이렇게 담길 것이다.

 

 

 

import java.util.Scanner;

public class NQueenBackTracking2 {

	static int N, ans;
	static int col[];
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		col = new int[N+1];
		ans = 0;
		setQueen(1); //첫 퀸은 무조건 넣을 수 있으므로 1부터 진행하며 안그런 경우 1을 넣기전에 available로 체크해야함
		System.out.println(ans);
		
	}
	
	static void setQueen(int rowNo) { // rowNo : 퀸을 두어야하는 현재 행
		
		
		//기저조건 퀸을 다 놓은 경우 - rowNo는 1부터 시작이므로 n보다 커야함
		//기저조건에 도착하면 바로 답인 이유는 답이 아닌 경우 가지치기로 사전에 체크함
		if(rowNo>N) {
			ans++;
			return;
		}
		
		//1열부터 n열까지 퀸을 놓는 시도
		for (int i = 1; i <= N; i++) {
			col[rowNo] = i;
			if(isAvailable(rowNo)) { //여기까지 가능했다면 이다음퀸이 가능한지 체크
				setQueen(rowNo+1);
			}
		}
		
	}
	
	static boolean isAvailable(int rowNo) { // 아까놓은 퀸 직전까지 퀸을 놓을 수 있는지 비교해야함 rowNo : 놓아진 마지막 퀸
		
		for (int i = 1; i < rowNo; i++) {
			if(col[rowNo] == col[i] || rowNo-i == Math.abs(col[rowNo] - col[i])) return false; //현재놓은 퀸 rowNo과 기존에 놓은 퀸 i 가 같은경우
		}
		return true;
	}
}
반응형
저작자표시 (새창열림)

'알고리즘' 카테고리의 다른 글

백준 14888 자바 연산자 끼워넣기  (1) 2022.03.22
백준 2580 스도쿠 자바  (0) 2022.03.19
프로그래머스 주차요금계산 자바  (0) 2022.03.16
백준 2470 자바 드래곤 커브  (0) 2022.03.09
백준 18870 자바  (1) 2022.03.09
    '알고리즘' 카테고리의 다른 글
    • 백준 14888 자바 연산자 끼워넣기
    • 백준 2580 스도쿠 자바
    • 프로그래머스 주차요금계산 자바
    • 백준 2470 자바 드래곤 커브
    은세고화
    은세고화

    티스토리툴바