문제
스도쿠는 18세기 스위스 수학자가 만든 '라틴 사각형'이랑 퍼즐에서 유래한 것으로 현재 많은 인기를 누리고 있다. 이 게임은 아래 그림과 같이 가로, 세로 각각 9개씩 총 81개의 작은 칸으로 이루어진 정사각형 판 위에서 이뤄지는데, 게임 시작 전 일부 칸에는 1부터 9까지의 숫자 중 하나가 쓰여 있다.

나머지 빈 칸을 채우는 방식은 다음과 같다.
- 각각의 가로줄과 세로줄에는 1부터 9까지의 숫자가 한 번씩만 나타나야 한다.
- 굵은 선으로 구분되어 있는 3x3 정사각형 안에도 1부터 9까지의 숫자가 한 번씩만 나타나야 한다.
위의 예의 경우, 첫째 줄에는 1을 제외한 나머지 2부터 9까지의 숫자들이 이미 나타나 있으므로 첫째 줄 빈칸에는 1이 들어가야 한다.

또한 위쪽 가운데 위치한 3x3 정사각형의 경우에는 3을 제외한 나머지 숫자들이 이미 쓰여있으므로 가운데 빈 칸에는 3이 들어가야 한다.

이와 같이 빈 칸을 차례로 채워 가면 다음과 같은 최종 결과를 얻을 수 있다.

게임 시작 전 스도쿠 판에 쓰여 있는 숫자들의 정보가 주어질 때 모든 빈 칸이 채워진 최종 모습을 출력하는 프로그램을 작성하시오.
입력
아홉 줄에 걸쳐 한 줄에 9개씩 게임 시작 전 스도쿠판 각 줄에 쓰여 있는 숫자가 한 칸씩 띄워서 차례로 주어진다. 스도쿠 판의 빈 칸의 경우에는 0이 주어진다. 스도쿠 판을 규칙대로 채울 수 없는 경우의 입력은 주어지지 않는다.
출력
모든 빈 칸이 채워진 스도쿠 판의 최종 모습을 아홉 줄에 걸쳐 한 줄에 9개씩 한 칸씩 띄워서 출력한다.
스도쿠 판을 채우는 방법이 여럿인 경우는 그 중 하나만을 출력한다.
접근 방식
대충 어떻게 풀어야 하는지 감은 왔는데
실제로 어떻게 구현해야 할지 조금 고민했던 문제이다
모든 칸을 방문해야 할지 혹은 모든 칸중에 0인 칸들만 방문해야 할지도 고민이였고
칸에 숫자를 모두 넣고 확인해야 할지 확인한 후에 맞는 숫자만 넣어야 할지도 고민이였다..!
결국엔 모든 칸을 방문하면서 칸에 숫자를 넣고 확인한 후 들어갈 수 있다면 재귀 함수를 반복할 수 있도록 구현하였다
숫자를 넣고 확인하는 과정은
1. 같은 열 확인
2. 같은 행 확인
3. 같은 3X3 내의 숫자 확인
이렇게 확인해주었다
막상 짜고 보니 간단했지만 고민을 많이 하게 됐던 문제였다..!
코드
#include<bits/stdc++.h>
using namespace std;
int sdk[9][9];
bool check(int x, int y, int val) {
for(int i=0; i<9; i++) {
if(sdk[x][i] == val) return false;
}
for(int i=0; i<9; i++) {
if(sdk[i][y] == val) return false;
}
int sx = 3 * (x / 3);
int sy = 3 * (y / 3);
for(int i = sx; i<sx + 3; i++) {
for(int j = sy; j<sy + 3; j++) {
if(sdk[i][j] == val) return false;
}
}
return true;
}
bool sol(int x, int y) {
if(x == 9) return true;
if(y == 9) return sol(x+1, 0);
if(sdk[x][y] != 0) return sol(x, y+1);
for(int i=1; i<=9; i++) {
if(check(x,y,i)) {
sdk[x][y] = i;
if(sol(x, y+1)) return true;
sdk[x][y] = 0;
}
}
return false;
}
int main() {
for(int i=0; i<9; i++) {
for(int j=0; j<9; j++) {
cin>>sdk[i][j];
}
}
sol(0,0);
for(int i=0; i<9; i++) {
for(int j=0; j<9; j++) {
cout<<sdk[i][j]<<" ";
}
cout<<"\n";
}
}
'Algorithm' 카테고리의 다른 글
[BOJ] 좋은수열 2661번 C++ (0) | 2024.06.21 |
---|---|
[BOJ] 가르침 1062번 C++ (0) | 2024.06.18 |
[BOJ] N-Queen 9663번 C++ (0) | 2024.06.11 |
[BOJ] 무기 공학 18430번 C++ (1) | 2024.06.11 |
[BOJ] 애너그램 6443번 C++ (1) | 2024.06.10 |