Time Limit: 1 second
Memory Limit: 512 mebibytes
One day, somebody talk to Mr.G : Do you know JCVB have been the champion of the world Sudoku championships. He can solve a Sudoku Crosswords in a minute. Mr.G said: Just so so.If give me a computer I can solve the problem in a second. But later he found his program couldn’t solve the problem only use 1 second. So, he gave the problem to you. Can you help him to solve the crossword?
Iuput
The input contains 9 lines, and each line contains 9 integers
S
i
,
1
,
S
i
,
2
,
…
S
i
,
9
S_{i,1}, S_{i,2}, \ldots S_{i,9}
Si,1,Si,2,…Si,9, describes the sudoku.
0 ≤
S
i
,
j
S_{i,j}
Si,j≤9,
S
i
,
j
S_{i,j}
Si,j=0 means the box(i,j) is empty.
Output
Print the whole crossword in the same format as input.
If there are multiple answers, output anyone of them. The answer exists.
Examples
Sample Input
2 0 0 0 1 0 8 9 0
0 0 7 0 0 0 0 0 0
0 0 0 9 0 0 0 0 7
0 6 0 0 0 1 3 0 0
0 9 0 7 3 4 0 8 0
0 0 3 6 0 0 0 5 0
6 0 0 0 0 2 0 0 0
0 0 0 0 0 0 1 0 0
0 5 9 0 8 0 0 0 3
Sample Output
2 4 5 3 1 7 8 9 6
9 1 7 2 6 8 5 3 4
3 8 6 9 4 5 2 1 7
4 6 2 8 5 1 3 7 9
5 9 1 7 3 4 6 8 2
8 7 3 6 2 9 4 5 1
6 3 8 1 7 2 9 4 5
7 2 4 5 9 3 1 6 8
1 5 9 4 8 6 7 2 3.
Note
Don’t think too much, just use … brute force?
#include <stdio.h>
#include <stdlib.h>
/* 子函数流程:
* 1 dfs搜索结束的条件
* 2 开始回溯的条件
* 3 正常情况下填入数字的流程
*/
void dfs(int Sudoku[9][9], int row, int col)
{
int count = 0, d[9] = {0}; //d是用来记录每一个可填入数的一维数组
int i, j;
//搜索结束,行列都累加到9
if(row==9 && col==9)
{
for(i=0; i<9; i++)
{
for(j=0; j<9; j++)
printf("%d ", Sudoku[i][j]);
printf("\n");
}
return ;
}
//开始回溯,即此格为0,需要填入数字
if(Sudoku[row][col] == 0)
{
for(int k=0; k<9; k++)
{
//行检验
if(Sudoku[row][k] != 0)
{
d[Sudoku[row][k]-1] = 1; //记录这个数字表示已有
}
//列检验
if(Sudoku[k][col] != 0)
{
d[Sudoku[k][col]-1] = 1;
}
}
//块检验
for(int m=(int)(row/3)*3; m<(int)(row/3)*3+3; m++)
{
for(int n=(int)(col/3)*3; n<(int)(col/3)*3+3; n++)
{
if(Sudoku[m][n] != 0)
d[Sudoku[m][n]-1] = 1;
}
}
for(int k=0; k<9; k++)
if(d[k] == 0)
count++;
if(count == 0) //解不对
return;
//有解时,填入d中记录可填入的数,再进行对行列数进入到下一个的操作,如
//若下一个满足回溯条件跳回原来的,则之前改变的还原
else
{
for(int k=0; k<9; k++)
{
if(d[k] == 0)
{
//填入d中记录的可填入数
Sudoku[row][col] = k+1;
d[k] = 1;
//再进行对行列数进入下一个的操作
//依次从左到右,从上到下
if(col == 8 && row == 8)
{
col++;
row++;
}
else if(col == 8 && row < 8)
{
col = 0;
row++;
}
else if(col<8 && row <= 8)
{
col++;
}
dfs(Sudoku, row, col); //进入下一格
//如果下一个满足回溯条件跳回原来的,则之前的改变还原
if(col == 0)
{
col = 8;
row--;
}
else
{
col--;
}
Sudoku[row][col] = 0;
d[k] = 0;
}
}
}
}
else //这一格中已经提供了数,则进行行列数的操作后,直接进入下一格
{
if(col == 8 && row == 8)
{
col++;
row++;
}
else if(col == 8 && row < 8)
{
col = 0;
row++;
}
else if(col <8 && row <=8)
{
col++;
}
dfs(Sudoku, row, col); //进入下一格
}
}
int main()
{
int Sudoku[9][9];
int i, j;
int row = 0, col=0;
for(i=0; i<9; i++)
for(j=0; j<9; j++)
scanf("%d", &Sudoku[i][j]);
dfs(Sudoku, row, col);
return 0;
}