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