9阶数独,如上题做
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string.h>
#include <vector>
using namespace std;
int puzzle[10][10];
char tmp[15];
const int SLOT=0;
const int ROW=1;
const int COL=2;
const int SUB=3;
const int maxn=400;
const int maxnode=9*9*9*9*9*4+100;
const int maxr=9*9*9*9*9*4+100;
struct DLX
{
int n , sz; // 行数,节点总数
int S[maxn]; // 各列节点总数
int row[maxnode],col[maxnode]; // 各节点行列编号
int L[maxnode],R[maxnode],U[maxnode],D[maxnode]; // 十字链表
int ansd,ans[maxn]; // 解
void init(int n )
{
this->n = n ;
for(int i = 0 ; i <= n; i++ )
{
U[i] = i ;
D[i] = i ;
L[i] = i - 1;
R[i] = i + 1;
}
R[n] = 0 ;
L[0] = n;
sz = n + 1 ;
memset(S,0,sizeof(S));
}
void addRow(int r,vector<int> c1)
{
int first = sz;
for(int i = 0 ; i < c1.size(); i++ ){
int c = c1[i];
L[sz] = sz - 1 ; R[sz] = sz + 1 ; D[sz] = c ; U[sz] = U[c];
D[U[c]] = sz; U[c] = sz;
row[sz] = r; col[sz] = c;
S[c] ++ ; sz ++ ;
}
R[sz - 1] = first ; L[first] = sz - 1;
}
// 顺着链表A,遍历除s外的其他元素
#define FOR(i,A,s) for(int i = A[s]; i != s ; i = A[i])
void remove(int c){
L[R[c]] = L[c];
R[L[c]] = R[c];
FOR(i,D,c)
FOR(j,R,i) {U[D[j]] = U[j];D[U[j]] = D[j];--S[col[j]];}
}
void restore(int c){
FOR(i,U,c)
FOR(j,L,i) {++S[col[j]];U[D[j]] = j;D[U[j]] = j; }
L[R[c]] = c;
R[L[c]] = c;
}
bool dfs(int d){
if(R[0] == 0 ){
ansd = d;
return true;
}
// 找S最小的列c
int c = R[0] ;
FOR(i,R,0) if(S[i] < S[c]) c = i;
remove(c);
FOR(i,D,c){
ans[d] = row[i];
FOR(j,R,i) remove(col[j]);
if(dfs(d + 1)) return true;
FOR(j,L,i) restore(col[j]);
}
restore(c);
return false;
}
bool solve(vector<int> & v){
v.clear();
if(!dfs(0)) return false;
for(int i = 0 ; i< ansd ;i ++ ) v.push_back(ans[i]);
return true;
}
};
DLX slover;
int encode(int a,int b,int c){
return a*81+b*9+c+1;
}
void decode(int code,int &a,int &b,int &c){
code--;
c=code%9; code/=9;
b=code%9; code/=9;
a=code;
}
void read(){
for(int i=0;i<9;i++){
scanf("%s",tmp);
for(int j=0;j<9;j++)
puzzle[i][j]=tmp[j]-'0';
}
}
int main(){
int kase;
scanf("%d",&kase);
while(kase--){
read();
slover.init(324);
for(int r=0;r<9;r++){
for(int c=0;c<9;c++){
for(int v=0;v<9;v++){
if(puzzle[r][c]==0||puzzle[r][c]==v+1){
vector<int> columns;
columns.push_back(encode(SLOT,r,c));
columns.push_back(encode(ROW,r,v));
columns.push_back(encode(COL,c,v));
columns.push_back(encode(SUB,(r/3)*3+c/3,v));
slover.addRow(encode(r,c,v),columns);
}
}
}
}
vector<int>ans;
slover.solve(ans);
for(int i=0;i<ans.size();i++){
int r,c,v;
decode(ans[i],r,c,v);
puzzle[r][c]=v+1;
}
for(int i=0;i<9;i++){
for(int j=0;j<9;j++)
printf("%d",puzzle[i][j]);
printf("\n");
}
}
return 0;
}