所以我试图用回溯来解决数独
这个例子: example_pic
我使用webSudoku(上图)给出的位置上的数字对二维数组中的一些索引进行了硬编码。 它肯定有解决方案,但我的代码打印“解决方案不存在
这是我的代码:
#include <stdio.h>
int a[10][10]= {{2,0,0,0,9,0,0,3,1},
{0,0,3,5,0,6,0,2,0},
{0,0,8,1,3,0,5,4,0},
{7,2,0,0,0,9,0,0,4},
{4,0,0,0,0,0,0,0,8},
{3,0,0,6,0,0,0,9,5},
{0,7,6,0,4,5,1,0,0},
{0,1,0,9,0,7,4,0,0},
{5,3,0,0,8,0,0,0,6}};
bool is_valid(int x, int y, int value){
if(a[x][y] != 0) return false;
//check_row and column
for(int tmp=1; tmp<=9; tmp++){
if(value == a[x][tmp]) return false;
}
for(int tmp=1; tmp<=9; tmp++){
if(value == a[tmp][y]) return false;
}
//check in 3*3 block
int x_s = (x-1)/3*3 + 1;
int y_s = 3*((y+2)/3-1)+1;
for(int ch_x = x_s; ch_x<x_s+3; ch_x++){
for(int ch_y=y_s; ch_y<y_s+3; ch_y++){
if(ch_x!=x && ch_y!=y){
if(value==a[ch_x][ch_y]) return false;
}
}
}
return true;
}
bool find(int &x, int &y){
// check if valid cells are exists
for(x=1; x<=9; x++){
for(y=1; y<=9; y++){
if(a[x][y] == 0)
return true;
}
}
return false;
}
bool solve(){
int x,y;
//base::case
if(!find(x,y)) return true;
for(int cand = 1; cand <=9; cand++){
if(is_valid(x,y,cand)){
a[x][y] = cand;
if(solve()) return true;
a[x][y] = 0;
}
}
return false;
}
void print(){
//print the sudoku plate
for(int i=1;i<=9; i++){
for(int j=1; j<=9; j++){
printf("%2d",a[i][j]);
}
printf("\n");
}
return ;
}
int main(){
//Fill in some empty grid with the known values
/*for(int i=1; i<=9; i++){
for(int j=1; j<=9; j++){
scanf("%1d",&a[i][j]);
}
}*/
if (solve()) print();
else printf("No solution exists\n");
return 0;
}
我猜我的'解决功能'或'is_valid'功能无效。
在'is_valid'函数中,如果有问题,则为
bool find(int &x, int &y){
// check if valid cells are exists
for(x=1; x<=9; x++){
for(y=1; y<=9; y++){
if(a[x][y] == 0)
return true;
}
}
return false;
}
但是,我也对这部分进行了硬编码,在我的范围内,似乎没有问题。
在'解决功能'中
bool solve(){
int x,y;
//base::case
if(!find(x,y)) return true;
for(int cand = 1; cand <=9; cand++){
if(is_valid(x,y,cand)){
a[x][y] = cand;
if(solve()) return true;
a[x][y] = 0;
}
}
return false;
}
我无法弄清楚我错在哪里。如果你在solve()函数中发现任何其他错误 - 请告诉我。因为我不确定我完全理解“回溯”的事情......
P.S。 :参考我读过(https://see.stanford.edu/materials/icspacs106b/H19-RecBacktrackExamples.pdf)
答案 0 :(得分:1)
有一些错误
(x, y)
和(row, col)
地址(行是y,而不是x)。选择一个表示并坚持下去is_valid
中存在拼写错误,因为对(c, x)
的检查应该在(c, y)
(或(y, c)
上,具体取决于约定,但肯定会使用y
而不是再次x
)int start_x = (x-1)/3*3 + 1, start_y = (y-1)/3*3 + 1;
修复代码在给定示例上工作的所有内容