C++解决数独问题(回溯)
输入一个数独作为9*9的数组,例如输入一个测试数据map[9][9]为:
0 9 0 0 0 0 0 6 0 8 0 1 0 0 0 5 0 9 0 5 0 3 0 4 0 7 0 0 0 8 0 7 0 9 0 0 0 0 0 9 0 8 0 0 0 0 0 6 0 2 0 7 0 0 0 8 0 7 0 5 0 4 0 2 0 5 0 0 0 8 0 7 0 6 0 0 0 0 0 9 0 解决思路为:设定一个count来计数,当count=81的时候,遍历完整个数组,这时可以输出结果; 从左上角的数字开始,如果该数为0,则在这个位置从1开始填,这时检查填入的数字能否填入,1没在第一行中出现,也没在第一列中出现,但是在3*3的格子中出现了,则这个位置变为2;再次检查2是否能填入,同理,发现也不能填入,则变成3,发现3可以填入。 以此类推,可以将第一行填满。当遇到冲突发现不能填数字时,将该位置变成0,再返回上一个数,将其+1;就是这样一个不断试值不断重复迭代,遇到冲突,返回纠错然后再迭代的过程。 代码理解:
void backtrace(int count)
{
//如果循环完81个数字,则打印出来
if (count == 81)
{
cout << "result is:" << endl;
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 9; ++j)
{
cout << map[i][j] << " ";
}
cout << endl;
}
return;
}
int row = count / 9;
int col = count % 9;
//如果该位置为0,
if (map[row][col] == 0)
{
for (int i = 1; i <= 9; ++i)
{
map[row][col] = i;//将1-9填入该位置
if (isPlace(count)) //判断填入的数时候能够放入
{
backtrace(count + 1);//如果可以放入,则对下一个位置进行操作
}
}
map[row][col] = 0;
}
//如果该位置不为0,则直接对下个位置的进行操作
else
{
backtrace(count + 1);
}
}
bool isPlace(int count)
{
int row = count / 9;
int col = count % 9;
int j;
//判断填入的数是否在该行
for (j = 0; j < 9; ++j)
{
if (map[row][j] == map[row][col] && j != col)
{
return false;
}
}
//判断填入的数是否在该列
for (j = 0; j < 9; ++j)
{
if (map[j][col] == map[row][col] && j != row)
{
return false;
}
}
//判断填入的数是否在3*3的小框中
int tempRow = row / 3 * 3;
int tempCol = col / 3 * 3;
for (j = tempRow; j < tempRow + 3; ++j)
{
for (int k = tempCol; k < tempCol + 3; ++k)
{
if (map[j][k] == map[row][col] && j!=row && k!=col)
{
return false;
}
}
}
return true;
}
输出为:
7 9 3 8 5 1 4 6 2 8 4 1 2 6 7 5 3 9 6 5 2 3 9 4 1 7 8 3 2 8 4 7 6 9 5 1 5 7 4 9 1 8 6 2 3 9 1 6 5 2 3 7 8 4 1 8 9 7 3 5 2 4 6 2 3 5 6 4 9 8 1 7 4 6 7 1 8 2 3 9 5
第一次写blog,如有错误,请多指教!~
