N-Queen(9663)
조금 더 복잡한 백트래킹 문제 1
Last updated
조금 더 복잡한 백트래킹 문제 1
Last updated
92import java.io.*;
import java.util.*;
public class Main{
static boolean visited[][];
static int count, N;
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
count=0;
//자바에서 boolean 배열을 생성하는 경우에 false값을 초기화되어있다!!
visited = new boolean[N][N];
dfs(visited, 0);
System.out.println(count);
}
public static void dfs(boolean [][]visited, int depth){
//이전까지의 n&m에서는 여기서 출력을 진행해줬지만 이번에는 숫자를 세는 게 포인트이기때문에 연산만.
if(depth==N){
count++;
return;
}
//기본적인 재귀를 사용하는 방식이고,
for (int i = 0; i < N; i++) {
if(fQueen(visited, depth, i)){
visited[depth][i] = true;
dfs(visited, depth+1);
visited[depth][i] = false;
}
}
}
public static boolean fQueen(boolean[][] visited, int x, int y){
//현재 점에서부터 세로를 검사해주고,
for (int i = 0; i < x; i++) {
if(visited[i][y] == true)
return false;
}
//와! for문 안에 변수를 2개나 넣어서 할 수도 있다는 사실!!!!
//원래는 이중for문써서 해볼려고하니까 그렇게 하기는 시간초과일꺼같기도하고 애초에 틀리기도해서
//이부분은 검색해봤더니 for문 안에 변수를 2개를 넣어서 해본사람이 많았다!!
//위로 대각선 검사해주고,
for (int i=x, j=y; i>=0&&j>=0; i--, j--) {
if(visited[i][j] == tru1e)
return false;
}
//아래로 대각선 검사해주고,
for (int i=x, j=y; i>=0&&j<N; i--, j++) {
if(visited[i][j] == true)
return false;
}
return true;
}
}import java.util.*;
import java.io.*;
public class Main{
static int n, sum=0;
static int[][] arr;
static boolean[][] visited;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
//퀸의 위치를 기억하기 위한 배열
arr = new int[n][n];
//퀸이 지나갈 수 있는 곳을 기억하기 위한 배열
visited = new boolean[n][n];
//깊이우선탐색
dfs(0);
System.out.println(sum);
}
public static void dfn(int cnt){
//만약 찾고있는 깊이가 한계까지 도달한다면 결과값 ++
if(cnt == n){
sum++;
return;
}
for(int i=0; i<n; i++){
//여기서부터는 기존 dfs의 구현과 유사하다
//일단 만약 체크를 했던 장소라면 넘어가고
if(visited[cnt][i])
continue;
//해당 위치에 들렀다고 체크하고
visited[cnt][i] = true;
//체크를 했으니까 퀸의 위치또한 저장해두고 진행
arr[cnt][i] = 1;
//퀸이 움직일 수 있는 곳을 모두 체크
QueenMove(cnt, i);
//재귀를 통해서 다음 dfs로 진행
dfs(cnt+1);
//만약 깊이가 끝까지 진행되었다면, return을 했을테지만 그냥 진행이 되었다면 여기까지 올 수 있음
//여기까지 도달했다는 의미는 퀸의 배치를 완료했다는 의미이다.
//다시 원상복구를 해줘야한다.
//체스판을 초기화 시키고
for(int j=0; j<n; j++){
for(int k=0; k<n; k++){
visited[j][k] = false;
}
}
//퀸을 빼주고
arr[cnt][i] = 0;
//이전에 두었던 퀸의 위치를 복원시켜준다
for(int j=0; j<n; j++){
for(int k=0; k<n; k++){
if(arr[j][k] == 1){
QueenMove(j, k);
}
}
}
}
}
//좌표를 생각하는게 반대이다..!
public static void QueenMove(int x, int y){
//세로로 움직이면서 확인
for(int i=x; i<n; i++){
if(!visited[i][y])
visited[i][y] = true;
}
//왼쪽 아래 대각선으로 확인
for(int i=x, j=y; i<n&&j<n; i++, j++){
if(!visited[i][j])
visited[i][j] = true;
}
//오른쪽 아래 대각선으로 확인
for(int i=x, j=y; i<n&&j>=0; i++, j--){
if(!visited[i][j])
visited[i][j] = true;
}
}
}