Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
관리 메뉴

Life Engineering

[BOJ 2239] 스도쿠 (Java) 본문

Problem Solving

[BOJ 2239] 스도쿠 (Java)

흑개 2022. 4. 6. 13:18

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

 

2239번: 스도쿠

스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다

www.acmicpc.net

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

public class Main_BOJ_2239 {
	static int[][] map=new int[10][10];
	static int[][] row=new int[10][10];
	static int[][] col=new int[10][10];
	static int[][] square=new int[10][10];
	static int cnt=0;
	static ArrayList<int[]> toFill=new ArrayList<>();
	static String answer;
	public static void main(String[] args) throws IOException {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		for (int i=1; i<=9; i++) {
			String s=br.readLine();
			for (int j=1; j<=9; j++) {
				int num=s.charAt(j-1)-'0';
				map[i][j]=num;
				if (num!=0) {
					row[i][num]=1;
					col[j][num]=1;
					square[checkSquareNum(i,j)][num]=1;
				}
				else {
					toFill.add(new int[] {i,j});
					cnt++;
				}
			}
		}
		backtracking(0);
		for (int i=0; i<81; i+=9) {
			System.out.println(answer.substring(i,i+9));
		}
	}
	
	private static boolean backtracking(int n) {
		if (n==cnt) {
			StringBuilder sb=new StringBuilder("");
			for (int i=1; i<=9; i++) {
				for (int j=1; j<=9; j++) {
					sb.append(map[i][j]);
				}
			}
			answer=sb.toString();
			return true;
		}
		int r=toFill.get(n)[0];
		int c=toFill.get(n)[1];
		for (int i=1; i<=9; i++) {
			if (row[r][i]==0 && col[c][i]==0 && square[checkSquareNum(r,c)][i]==0) {
				mark(r,c,i,1);
				if (backtracking(n+1)) return true;
				mark(r,c,i,0);
			}
		}
		return false;
		
	}
	
	private static void mark(int r, int c, int i, int val) {
		row[r][i]=val;
		col[c][i]=val;
		square[checkSquareNum(r,c)][i]=val;
		if (val==1) map[r][c]=i;
		else map[r][c]=0;
	}

	private static int checkSquareNum(int r, int c) {
		if (r>=1 && r<4) {
			if (c>=1 && c<4) return 1;
			else if (c>=4 && c<7) return 2;
			else return 3;
		}
		else if (r>=4 && r<7) {
			if (c>=1 && c<4) return 4;
			else if (c>=4 && c<7) return 5;
			else return 6;
		}
		else {
			if (c>=1 && c<4) return 7;
			else if (c>=4 && c<7) return 8;
			else return 9;
		}
	}

}

백트래킹 문제.

row 배열, col배열, square 배열을 따로 두어서 현재 넣으려고 하는 (row, col, square)에서  i번째 (row, col, square)에 현재 숫자가 있는지 체크하도록 했다.

 

나는 0인 것을 모아서 그것만 backtracking을 돌렸는데,

다른 분들의 코드를 보니 81개를 다 돌면서, 만약 map[row][col]이 0이 아니면 backtracking(i+1) 하는 식으로 다음번째로 넘겨주고 0이면 탐색 작업을 수행하는 식으로 했다. 

 

또한 checkSquareNum 함수를 쓸 필요 없이, (r/3)*3+(c/3) 으로 정사각형 번호를 나타낼 수 있다. 

'Problem Solving' 카테고리의 다른 글

[BOJ 13459] 구슬 탈출 (Java)  (0) 2022.04.06
[BOJ 17471] 게리맨더링 (Java)  (0) 2022.04.06
[BOJ 10159] 저울 (Java)  (0) 2022.04.05
[JUNGOL 2577] 회전 초밥(고)  (0) 2022.04.05
[SWEA 5656] 벽돌 깨기 (Java)  (0) 2022.04.05