2580번: 스도쿠
사용 언어: C++
풀이
문제 요약
9×9 스도쿠 판에서, 일부 칸이 비어 있고(0으로 표시됨), 규칙에 맞게 모든 칸을 채워야 함.
- 각 행에 1~9가 한번씩
- 각 열에 1~9가 한번씩
- 각 3×3 구역에 1~9가 한번씩
풀이
백트래킹 기법을 이용하여 모든 빈 칸에 대해 가능한 수를 대입하고,
불가능한 경우 이전 상태로 돌아가서 다른 수를 시도.
핵심 아이디어
- 빈 칸을 순서대로 탐색하며 가능한 숫자를 시도
- 숫자를 채울 때마다, 행/열/구역 사용 여부를 표시
- 가능한 경우 다음 칸으로 재귀 호출
- 실패하면 상태를 되돌리고 다음 숫자 시도 (백트래킹)
구현 포인트
- 각 행/열/3×3 구역에 대해 숫자 사용 여부를 확인하기 위해
bool row[9][10], col[9][10], square[9][10] 배열을 사용한다. - (i / 3) * 3 + (j / 3)로 3×3 구역 번호 계산
- 0~80까지 순차적으로 인덱스화하여 빈 칸을 처리
#include <iostream>
using namespace std;
int board[9][9];
bool row[9][10];
bool col[9][10];
bool square[9][10];
int squareIndex(int i, int j) {
return (i / 3) * 3 + (j / 3);
}
bool solve(int idx = 0) {
if (idx == 81) return true;
int i = idx / 9;
int j = idx % 9;
if (board[i][j] != 0) return solve(idx + 1);
for (int num = 1; num <= 9; num++) {
int sq = squareIndex(i, j);
if (!row[i][num] && !col[j][num] && !square[sq][num]) {
board[i][j] = num;
row[i][num] = col[j][num] = square[sq][num] = true;
if (solve(idx + 1)) return true;
board[i][j] = 0;
row[i][num] = col[j][num] = square[sq][num] = false;
}
}
return false;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
cin >> board[i][j];
int num = board[i][j];
if (num != 0) {
row[i][num] = true;
col[j][num] = true;
square[squareIndex(i, j)][num] = true;
}
}
}
solve();
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++)
cout << board[i][j] << ' ';
cout << '\n';
}
return 0;
}
'BOJ > 백트래킹' 카테고리의 다른 글
14889번: 스타트와 링크 (0) | 2025.06.04 |
---|---|
14888번: 연산자 끼워넣기 (1) | 2025.06.04 |
1799번: 비숍 (BOJ C/C++) (0) | 2022.09.08 |
18809번: Gaaaaaaaaaarden (0) | 2022.09.07 |
16987번: 계란으로 계란치기 (BOJ C/C++) (0) | 2022.09.06 |