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