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 }
posted on 2012-07-26 00:43  DrunBee  阅读(206)  评论(0编辑  收藏  举报