// topic Link http://poj.org/problem?id=3074
// exact cover problem solving reprint: https://www.cnblogs.com/grenet/p/3145800.html
// Sudoku problem into the exact cover problem reprint: https://www.cnblogs.com/grenet/p/3163550.html
. 1 #include <cstdio> 2 #include <CString> . 3 #include <Vector> . 4 the using namespace STD; . 5 . 6 // const int. 1 << INF = 30; . 7 const int MAXN = 729 ; . 8 const int maxnode = 2916 ; . 9 const int maxnr = 729 ; 10 . 11 // row number starting from 1, column number is 1 ~ n, the header node 0 is node; node 1 ~ n is a virtual node in each column top 12 is struct DLX { 13 is int n-, SZ; // number of columns, the total number of node 14 int S [MAXN]; // each column nodes 15 16 int Row [maxnode], COL [maxnode]; // each node row number . 17 int L [maxnode], R & lt [maxnode], the U-[maxnode], D [maxnode]; // orthogonal list 18 is . 19 int ANSD, ANS [maxnr]; // solution 20 is 21 is void the init ( int n-) { // n-columns is 22 is the this -> = n- n-; 23 is 24 // virtual node 25 for ( int I = 0 ; I <= n-; ++ I) { 26 U[i] = i; 27 D[i] = i; 28 L[i] = i-1; 29 R[i] = i+1; 30 } 31 R[n] = 0; L[0] = n; 32 33 sz = n + 1; 34 memset(S, 0, sizeof(S)); 35 } 36 37 void addRow(int r, vector<int> columns) { 38 int first = sz; 39 for(int i = 0; i != columns.size(); ++i) { 40 int c = columns[i]; 41 L[sz] = sz-1; R[sz] = sz+1; D[sz] = c; U[sz] = U[c]; 42 D[U[c]] = sz; U[c] = sz; 43 row[sz] = r; col[sz] = c; 44 S[c]++; sz++; 45 } 46 R[sz-1] = first; L[first] = sz-1; 47 } 48 // 顺着链表A, 遍历除s外的其它元素 49 #define FOR(i, A, s) for(int i = A[s]; i != s; i = A[i]) 50 51 void remove(int c) { 52 L[R[c]] = L[c]; 53 R[L[c]] = R[c]; 54 FOR(i, D, c) 55 FOR(j, R, i) { 56 U[D[j]] = U[j]; 57 D[U[j]] = D[j]; 58 --S[col[j]]; 59 } 60 } 61 62 void restore(int c) { 63 FOR(i, U, c) 64 FOR(j, L, i) { 65 ++S[col[j]]; 66 U[D[j]] = j; 67 D[U[j]] = j; 68 } 69 L[R[c]] = c; 70 R[L[c]] = c; 71 } 72 73 // d为递归深度 74 bool dfs(int d) { 75 if(R[0] == 0 ) { // find the solution 76 ANSD = D; // length of the recording Solution 77 return to true ; 78 } 79 80 // Get s minimum column C 81 int C = R & lt [ 0 ]; // first deleted column 82 the FOR (I, R & lt, 0 ) IF (S [I] <S [c]) c = I; 83 84 remove (c); // delete c column 85 the FOR (I, D, c) { / / cover the first column with a row c i where the node 86 ANS [D] = Row [i]; 87 the FOR (J, R & lt, i) Remove (COL [J]); // delete the node i row to cover all of the other columns 88 IF (DFS (D + . 1 )) return to true ; 89 the FOR (J, L, i) restore (COL [J]); // restore all the other columns in the row node i can cover 90 } 91 is restore (c); // restoration column c 92 93 return to false ; 94 } 95 96 BOOL Solve (Vector < int > & V) { 97 v.clear (); 98 if(!dfs(0)) return false; 99 for(int i = 0; i != ansd; ++i) v.push_back(ans[i]); 100 return true; 101 } 102 }; 103 104 const int SLOT = 0; 105 const int ROW = 1; 106 const int COL = 2; 107 const int SUB = 3; 108 109 inline int encode(int a, int b, int c) { 110 return a*81 + b*9 + c + 1; 111 } 112 113 inline void decode(int code, int &a, int &b, int &c) { 114 code--; 115 c = code%9; code /= 9; 116 b = code%9; code /= 9; 117 a = code; 118 } 119 120 DLX solver; 121 122 int main() { 123 char str[81]; 124 char puzzle[9][9]; 125 while(scanf("%s", str) == 1 && strcmp(str, "end")) { 126 solver.init(324); 127 for(int i = 0; i != 9; ++i) { 128 for(int j = 0; j != 9; ++j) { 129 puzzle[i][j] = str[i*9 + j]; 130 } 131 } 132 for(int r = 0; r != 9; ++r) { 133 for(int c = 0; c != 9; ++c) { 134 for(int v = 0; v != 9; ++v) { 135 if(puzzle[r][c] == '.' || puzzle[r][c]-'0' == v+1) { 136 vector<int> columns; 137 columns.push_back(encode(SLOT, r, c)); 138 columns.push_back(encode(ROW, r, v)); 139 columns.push_back(encode(COL, c, v)); 140 columns.push_back(encode(SUB, (r/3)*3 + c/3, v)); 141 solver.addRow(encode(r, c, v), columns); 142 } 143 } 144 } 145 } 146 vector<int> ans; 147 solver.solve(ans); 148 149 for(int i = 0; i != ans.size(); ++i) { 150 int r, c, v; 151 decode(ans[i], r, c, v); 152 puzzle[r][c] = '1'+v; 153 } 154 for(int i = 0; i != 9; ++i) { 155 for(int j = 0; j != 9; ++j) { 156 printf("%c", puzzle[i][j]); 157 } 158 } 159 printf("\n"); 160 } 161 return 0; 162 }