1 #include<cstdio> 2 #include<cstring> 3 #define SD 16 4 #define MAXN 2400000 5 #define MAXM 4100 6 #define INF 0x7FFFFFFF 7 char sd[SD][SD]; 8 int L[MAXN], R[MAXN], U[MAXN], D[MAXN], C[MAXN], X[MAXN]; 9 int size, cnt, row, S[MAXM], H[MAXM], Q[MAXM], ans[MAXM]; 10 bool vis[MAXM]; 11 void Init(int m) 12 { 13 int i; 14 for (i = 0; i <= m; i++) 15 { 16 R[i] = i + 1; 17 L[i + 1] = i; 18 U[i] = D[i] = i; 19 S[i] = 0; 20 } 21 R[m] = 0; 22 size = m + 1; 23 } 24 void Remove(int c) 25 { 26 int i, j; 27 L[R[c]] = L[c]; 28 R[L[c]] = R[c]; 29 for (i = D[c]; i != c; i = D[i]) 30 { 31 for (j = R[i]; j != i; j = R[j]) 32 { 33 U[D[j]] = U[j]; 34 D[U[j]] = D[j]; 35 S[C[j]]--; 36 } 37 } 38 } 39 void Resume(int c) 40 { 41 int i, j; 42 L[R[c]] = c; 43 R[L[c]] = c; 44 for (i = D[c]; i != c; i = D[i]) 45 { 46 for (j = R[i]; j != i; j = R[j]) 47 { 48 U[D[j]] = j; 49 D[U[j]] = j; 50 S[C[j]]++; 51 } 52 } 53 } 54 inline void Link(int r, int c) 55 { 56 D[size] = D[c]; 57 U[size] = c; 58 U[D[c]] = size; 59 D[c] = size; 60 if (H[r] < 0) 61 H[r] = L[size] = R[size] = size; 62 else 63 { 64 L[size] = H[r]; 65 R[size] = R[H[r]]; 66 L[R[H[r]]] = size; 67 R[H[r]] = size; 68 } 69 S[c]++; 70 X[size] = r; 71 C[size++] = c; 72 } 73 void Build(int n) 74 { 75 int i, j, k, t; 76 Init(n * n << 2); 77 if (n == 4) 78 t = 2; 79 else if (n == 9) 80 t = 3; 81 else 82 t = 4; 83 for (i = row = 0; i < n; i++) 84 { 85 for (j = 0; j < n; j++) 86 { 87 if (sd[i][j] == '.') 88 { 89 for (k = 0; k < n; k++) 90 { 91 H[++row] = -1; 92 Q[row] = k; 93 Link(row, i * n + k + 1); 94 Link(row, n * n + j * n + k + 1); 95 Link(row, (n * n << 1) + (i / t * t + j / t) * n + k + 1); 96 Link(row, n * n * 3 + i * n + j + 1); 97 } 98 } 99 else 100 { 101 if (sd[i][j] >= '0' && sd[i][j] <= '9') 102 k = sd[i][j] - '1'; 103 else 104 k = sd[i][j] - 'A' + 9; 105 H[++row] = -1; 106 Q[row] = k; 107 Link(row, i * n + k + 1); 108 Link(row, n * n + j * n + k + 1); 109 Link(row, (n * n << 1) + (i / t * t + j / t) * n + k + 1); 110 Link(row, n * n * 3 + i * n + j + 1); 111 } 112 } 113 } 114 } 115 bool Dance(bool flag) 116 { 117 int i, j, temp, c; 118 if (R[0] == 0) 119 { 120 if (flag && !cnt) 121 { 122 for (i = j = 1; i <= row; i++) 123 { 124 if (vis[i]) 125 ans[j++] = Q[i]; 126 } 127 } 128 cnt++; 129 return cnt > 1; 130 } 131 for (temp = INF,i = R[0]; i; i = R[i]) 132 { 133 if (temp > S[i]) 134 { 135 temp = S[i]; 136 c = i; 137 } 138 } 139 Remove(c); 140 for (i = D[c]; i != c; i = D[i]) 141 { 142 vis[X[i]] = true; 143 for (j = R[i]; j != i; j = R[j]) 144 Remove(C[j]); 145 if (Dance(flag)) 146 return true; 147 for (j = L[i]; j != i; j = L[j]) 148 Resume(C[j]); 149 vis[X[i]] = false; 150 } 151 Resume(c); 152 return false; 153 } 154 bool OK(int n) 155 { 156 int i, j; 157 char temp; 158 for (i = 0; i < n; i++) 159 { 160 for (j = 0; j < n; j++) 161 { 162 if (sd[i][j] != '.') 163 { 164 temp = sd[i][j]; 165 sd[i][j] = '.'; 166 Build(n); 167 cnt = 0; 168 Dance(false); 169 if (cnt < 2) 170 return false; 171 sd[i][j] = temp; 172 } 173 } 174 } 175 return true; 176 } 177 int main() 178 { 179 int n, i, j; 180 while (~scanf("%d", &n)) 181 { 182 n *= n; 183 for (cnt = i = 0; i < n; i++) 184 { 185 for (j = 0; j < n; j++) 186 scanf(" %c", &sd[i][j]); 187 } 188 memset(vis, false, sizeof(vis)); 189 Build(n); 190 Dance(true); 191 if (cnt == 0) 192 puts("No Solution"); 193 else if (cnt > 1) 194 puts("Multiple Solutions"); 195 else 196 { 197 if (OK(n)) 198 { 199 for (i = 1; i <= n * n; i++) 200 { 201 if (ans[i] < 9) 202 putchar(ans[i] + 1 + '0'); 203 else 204 putchar(ans[i] - 9 + 'A'); 205 if (i % n == 0) 206 putchar('\n'); 207 } 208 } 209 else 210 puts("Not Minimal"); 211 } 212 } 213 return 0; 214 }