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 }
posted on 2012-07-24 21:57  DrunBee  阅读(270)  评论(0编辑  收藏  举报