Introduction
数独是一项非常简单的任务。如图所示,将具有9行9列的正方形表划分为9个较小的正方形3x3。在某些单元格中写入从1到9的十进制数字。其他单元格为空。目标是用1到9的十进制数字填充空单元格,每个单元格一位数字,以这种方式在每一行,每一列和每个标记的3x3子正方形中都显示1到9的所有数字。编写程序以解决给定的Sudoku任务。
Input
输入数据将从测试用例的数量开始。对于每个测试用例,紧跟着表的行的是9行。在每一行上,给出了一个准确的9位十进制数字的字符串,对应于该行中的单元格。如果单元格为空,则用0表示。
Output
对于每个测试用例,您的程序应以与输入数据相同的格式打印解决方案。空单元格必须根据规则进行填充。如果解决方案不是唯一的,则程序可以打印其中任何一种。
Sample Input
1
103000509
002109400
000704000
300502006
060000050
700803004
000401000
009205800
804000107
Sample Output
143628579
572139468
986754231
391542786
468917352
725863914
237481695
619275843
854396127
Answer
#include<iostream>
#include<cstring>
#define B(i,j) (i-1)/3*3+(j-1)/3+1
using namespace std;
int A[10][10];
bool V[3][10][10];
void visit(int i,int j,int k,int f){
V[0][i][k] = f;
V[1][j][k] = f;
V[2][B(i,j)][k] = f;
A[i][j] = f;
}
pair<int,int> go(int i,int j){
pair<int,int> n;
n.first = j==9 ? i+1:i;
n.second = j==9 ? 1:j+1;
return n;
}
bool dfs(int i,int j){
pair<int,int> nx=go(i,j);
if(i==10) return 1;
if(A[i][j])
return dfs(nx.first,nx.second);
for(int k=1;k<=9;k++){
bool exist=V[0][i][k]+V[1][j][k]+V[2][B(i,j)][k];
if(!exist){
visit(i,j,k,k);
if( dfs(nx.first,nx.second) )
return 1;
else
visit(i,j,k,0);
}
}
return 0;
}
int main(){
int n;
cin>>n;
while (n--){
memset(A,0,sizeof(A));
memset(V,0,sizeof(V));
for(int i=1;i<=9;i++){
string str;
cin>>str;
for(int j=1;j<=9;j++)
visit(i,j,str[j-1]-'0',str[j-1]-'0');
}
dfs(1,1);
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++)
cout<<A[i][j];
cout<<endl;
}
cout<<endl;
}
return 0;
}