반응형
출처 : www.acmicpc.net/problem/2239
문제
스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다음을 보자.
위 그림은 참 잘도 스도쿠 퍼즐을 푼 경우이다. 각 행에 1부터 9까지의 숫자가 중복 없이 나오고, 각 열에 1부터 9까지의 숫자가 중복 없이 나오고, 각 3×3짜리 사각형(9개이며, 위에서 색깔로 표시되었다)에 1부터 9까지의 숫자가 중복 없이 나오기 때문이다.
하다 만 스도쿠 퍼즐이 주어졌을 때, 마저 끝내는 프로그램을 작성하시오.
입력
9개의 줄에 9개의 숫자로 보드가 입력된다. 아직 숫자가 채워지지 않은 칸에는 0이 주어진다.
출력
9개의 줄에 9개의 숫자로 답을 출력한다. 답이 여러 개 있다면 그 중 사전식으로 앞서는 것을 출력한다. 즉, 81자리의 수가 제일 작은 경우를 출력한다.
풀이방법
1. DFS
코드
import java.awt.List;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class 스도쿠_2239 {
static boolean[][] visited;
static int[][] sudoku;
static ArrayList<Point> arr = new ArrayList<>() ;
static boolean isfinished = false;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
sudoku = new int[9][9];
visited = new boolean[9][9];
for (int i = 0; i < 9; i++) {
//st = new StringTokenizer(br.readLine(),"");
String str = br.readLine();
for (int j = 0; j < 9; j++) {
//sudoku[i][j] = Integer.parseInt(st.nextToken());
sudoku[i][j] = str.charAt(j) - '0';
if( sudoku[i][j] == 0 ) {
arr.add(new Point(i,j));
//System.out.println("I : " +i+" J : " + j);
}
}
}
dfs(0);
//print();
}
private static void print() {
for(int i=0; i<9; i++) {
for( int j=0; j<9; j++) {
System.out.print(sudoku[i][j]);
}
System.out.println();
}
}
public static void dfs(int index ) {
if( index >= arr.size() ) {
isfinished = true;
print();
return;
}
if( isfinished) return;
Point cur = arr.get(index);
int r= cur.x;
int c= cur.y;
for( int i=1; i<10; i++) {
int tmp = sudoku[r][c];
// 가로행 없고
// 세로행 없고
// 3*3 에 아무것도 없고
if( !isR(r,i) || !isC(c,i) || !isM(r,c,i)) continue;
//System.out.println("r : "+ r + " C : " + c + " vlaue : " + i);
// 갱신
sudoku[r][c] = i;
// dfs
dfs(index+1);
// 원상복구
sudoku[r][c] = tmp;
}
}
private static boolean isM(int r, int c, int value) {
// TODO Auto-generated method stub
int SR = r/3 *3;
int SC = c/3 *3;
for( int i=0; i<3; i++) {
for( int j=0; j<3; j++ ) {
if( sudoku[SR+i][SC+j] == value) return false;
}
}
return true;
}
private static boolean isC(int c, int value) {
// TODO Auto-generated method stub
for( int i=0; i<9; i++) {
if( sudoku[i][c] == value) return false;
}
return true;
}
private static boolean isR(int r, int value) {
for( int i=0; i<9; i++) {
if( sudoku[r][i] == value) return false;
}
return true;
}
}
반응형
'알고리즘' 카테고리의 다른 글
[프로그래머스] 베스트 앨범 [JAVA] (0) | 2020.11.08 |
---|---|
[삼성 SW Expert Academy] 등산로 1949[JAVA] (0) | 2020.11.04 |
[프로그래머스] 타겟 넘버 [JAVA] (0) | 2020.10.31 |
[프로그래머스] 주식가격 [JAVA] (0) | 2020.10.31 |
[백준] 파티 1238 [JAVA] (0) | 2020.10.31 |