#include <iostream>
#define UNASSIGNED 0
#define N 9
bool FindUnassignedLocation(int grid[N][N], int &row, int &col);
bool isSafe(int grid[N][N], int row, int col, int num);
/* Hàm giải Sudoku */
bool SolveSudoku(int grid[N][N]) {
int row, col;
// Nếu không còn vị trí nào chưa được gán, chúng ta đã giải xong
if (!FindUnassignedLocation(grid, row, col))
return true;
// thử nghiệm các số từ 1 đến 9
for (int num = 1; num <= 9; num++) {
// nếu nhìn thấy một số hợp lệ, gán nó và tiếp tục
if (isSafe(grid, row, col, num)) {
grid[row][col] = num;
// trả về true nếu tiếp tục và thành công
if (SolveSudoku(grid))
return true;
// nếu không thành công, hủy gán và thử lại
grid[row][col] = UNASSIGNED;
}
}
// nếu các số từ 1 đến 9 đều không hợp lệ, trả về false
return false;
}
/* Tìm kiếm vị trí chưa được gán trên bảng Sudoku */
bool FindUnassignedLocation(int grid[N][N], int &row, int &col) {
for (row = 0; row < N; row++)
for (col = 0; col < N; col++)
if (grid[row][col] == UNASSIGNED)
return true;
return false;
}
/* Kiểm tra xem có thể gán num vào vị trí (row, col) không */
bool isSafe(int grid[N][N], int row, int col, int num) {
// Kiểm tra hàng và cột
for (int d = 0; d < N; d++)
if (grid[row][d] == num || grid[d][col] == num)
return false;
// Kiểm tra hộp 3x3
int startRow = row - row % 3, startCol = col - col % 3;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (grid[i + startRow][j + startCol] == num)
return false;
return true;
}
/* In bảng Sudoku */
void printGrid(int grid[N][N]) {
for (int row = 0; row < N; row++) {
for (int col = 0; col < N; col++)
std::cout << grid[row][col] << " ";
std::cout << std::endl;
}
}
int main() {
int grid[N][N] = {{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9}};
if (SolveSudoku(grid) == true)
printGrid(grid);
else
std::cout << "Không có giải pháp nào tồn tại";
return 0;
}