import java.util.Scanner;
class Sudoku_rec {
class Grid { //포인터like 사용을 위한 클래스
public int v;
Grid(int n) {v = n;}
}
int rn, cn;
boolean[] num;
this.rn = rn;
this.cn = cn;
num = new boolean[] { true, true, true, true, true, true, true,
true, true };
}
};
Grid r[][] = new Grid[9][9]; // 행
Grid c[][] = new Grid[9][9]; // 열
Grid s[][] = new Grid[9][9]; // 구역
/* 본격 스도쿠 풀이 함수 */
Sudoku_rec() { //열,행,섹터 포인터
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
c[j][i] = r[i][j] = new Grid(0);
for (int rn = 0; rn < 9; rn += 3)
for (int cn = 0; cn < 9; cn += 3)
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
s[rn + (cn / 3)][i * 3 + j] = r[rn + i][cn + j];
}
int sizeofNumset
(Set set
) { // 가능한 숫자 개수 카운터 int cnt = 0;
for (boolean b : set.num)
if (b) cnt++;
return cnt;
}
Set findAblNum
(int rn,
int cn
) { // 해당 칸의 가능한 숫자 세트 탐색 Set nums
= new Set(rn, cn
); // true로 초기화 int sn = rn / 3 * 3 + cn / 3; // 섹터 번호 구함
for (int i = 0; i < 9; i++) {
// 행(*r),열(*c),섹터(*s) 탐색
if (r[rn][i].v > 0) // 채워져 있으면
nums.num[r[rn][i].v - 1] = false; // 마킹
if (c[cn][i].v > 0)
nums.num[c[cn][i].v - 1] = false;
if (s[sn][i].v > 0)
nums.num[s[sn][i].v - 1] = false;
}
return nums;
}
Set findMinPossible
() { // 가장 경우의 수가 적은칸의 세트 리턴 int size = 10;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (r[i][j].v > 0)
continue; // 채워진칸 무시
Set temp
= findAblNum
(i, j
); int nsize = sizeofNumset(temp);
if (nsize == 0) // 빈칸인데 가능한 숫자가 없으면
return new Set(10,
10); // 오답 표시 리턴 else if (nsize == 1) // 가능한 숫자가 하나일 경우 바로 리턴
return temp;
else if (nsize < size) {
size = nsize;
minset = temp;
}
}
}
return minset;
}
boolean solve() {
Set set
= findMinPossible
(); // 가장 경우의 수가 적은 칸 탐색 if (set == null) // 더 이상 빈칸이 없음을 뜻함.
return true; // 풀린것!
if (set.rn > 9) // 불가능한 칸이 있음을 뜻함
return false;
for (int i = 1; i <= 9; i++) { // 숫자 1~9를 채우는 부분
if (!set.num[i - 1])
continue; // 불가능한 숫자는 스킵
r[set.rn][set.cn].v = i; // 가능한 숫자를 채움
if (solve()) // 채운걸 풀어봄
return true; // 그게 풀렸으면 탈출
}
// 채울 수 있는 숫자가 없거나 다 채워봤는데 안된거니까
r[set.rn][set.cn].v = 0; // 지우고
return false; // 오답 리턴
}
void run() {
Scanner sc
= new Scanner
(System.
in); for (int i = 0; i < 9; i++) {
char input[] = sc.nextLine().toCharArray();
for (int j = 0; j < 9; j++)
r[i][j].v = input[j] - '0';
}
sc.close();
System.
out.
println(solve
() ? "[Solved]" : "[No solution]");
//결과 출력
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
}
}
public static void main
(String[] args
) { new Sudoku_rec().run();
}
}