【HDU】4210 Sudominoku

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #define MAXN 300000
  5 #define MAXL 1010
  6 #define MAXM 10
  7 #define INF 0x7FFFFFFF
  8 using namespace std;
  9 int L[MAXN], R[MAXN], U[MAXN], D[MAXN];
 10 int S[MAXL], H[MAXL], C[MAXN], X[MAXN], Q[MAXL];
 11 bool vis[MAXM][MAXM], G[MAXM][MAXM], has[MAXL];
 12 int size, row, a[MAXM][MAXM];
 13 int go[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
 14 void Init(int n, int m) {
 15     int i;
 16     memset(vis, false, sizeof(vis));
 17     memset(has, false, sizeof(has));
 18     memset(a, 0, sizeof(a));
 19     memset(G, false, sizeof(G));
 20     for (i = 0; i <= n; i++)
 21         H[i] = -1;
 22     for (i = 0; i <= m; i++) {
 23         L[i + 1] = i;
 24         R[i] = i + 1;
 25         U[i] = D[i] = i;
 26         S[i] = 0;
 27     }
 28     R[m] = 0;
 29     size = m + 1;
 30 }
 31 void Link(int r, int c) {
 32     U[size] = c;
 33     D[size] = D[c];
 34     U[D[c]] = size;
 35     D[c] = size;
 36     if (H[r] < 0)
 37         H[r] = L[size] = R[size] = size;
 38     else {
 39         L[size] = H[r];
 40         R[size] = R[H[r]];
 41         L[R[H[r]]] = size;
 42         R[H[r]] = size;
 43     }
 44     S[c]++;
 45     X[size] = r;
 46     C[size++] = c;
 47 }
 48 void Remove(int c) {
 49     int i, j;
 50     L[R[c]] = L[c];
 51     R[L[c]] = R[c];
 52     for (i = D[c]; i != c; i = D[i]) {
 53         for (j = R[i]; j != i; j = R[j]) {
 54             U[D[j]] = U[j];
 55             D[U[j]] = D[j];
 56             S[C[j]]--;
 57         }
 58     }
 59 }
 60 void Resume(int c) {
 61     int i, j;
 62     L[R[c]] = R[L[c]] = c;
 63     for (i = D[c]; i != c; i = D[i]) {
 64         for (j = R[i]; j != i; j = R[j]) {
 65             U[D[j]] = D[U[j]] = j;
 66             S[C[j]]++;
 67         }
 68     }
 69 }
 70 bool DFS(int now) {
 71     if (now > 81)
 72         return true;
 73     int x, y, nx, ny, i;
 74     x = (now - 1) / 9 + 1;
 75     y = now - (x - 1) * 9;
 76     if (vis[x][y])
 77         return DFS(now + 1);
 78     vis[x][y] = true;
 79     for (i = 0; i < 4; i++) {
 80         nx = x + go[i][0];
 81         ny = y + go[i][1];
 82         if (nx > 0 && nx < 10 && ny > 0 && ny < 10 && !vis[nx][ny]
 83                 && !G[a[x][y]][a[nx][ny]]) {
 84             vis[nx][ny] = true;
 85             G[a[x][y]][a[nx][ny]] = G[a[nx][ny]][a[x][y]] = true;
 86             if (DFS(now + 1))
 87                 return true;
 88             G[a[x][y]][a[nx][ny]] = G[a[nx][ny]][a[x][y]] = false;
 89             vis[nx][ny] = false;
 90         }
 91     }
 92     vis[x][y] = false;
 93     return false;
 94 }
 95 bool Dance() {
 96     int i, j, k, temp, c;
 97     if (R[0] == 0) {
 98         for (i = j = k = 1; i < row; i++) {
 99             if (has[i]) {
100                 a[j][k] = Q[i];
101                 k++;
102                 if (k > 9) {
103                     k = 1;
104                     j++;
105                 }
106             }
107         }
108         if (DFS(1)) {
109             for (i = 1; i < 10; i++) {
110                 for (j = 1; j < 10; j++)
111                     printf("%d", a[i][j]);
112                 putchar('\n');
113             }
114             return true;
115         }
116         return false;
117     }
118     for (temp = INF, i = R[0]; i; i = R[i]) {
119         if (temp > S[i]) {
120             temp = S[i];
121             c = i;
122         }
123     }
124     Remove(c);
125     for (i = D[c]; i != c; i = D[i]) {
126         has[X[i]] = true;
127         for (j = R[i]; j != i; j = R[j])
128             Remove(C[j]);
129         if (Dance())
130             return true;
131         for (j = L[i]; j != i; j = L[j])
132             Resume(C[j]);
133         has[X[i]] = false;
134     }
135     Resume(c);
136     return false;
137 }
138 int main() {
139     int ca = 1;
140     int n, i, j, k, x1, x2;
141     char y1, z1, y2, z2;
142     while (scanf("%d", &n), n) {
143         Init(729, 324);
144         for (i = 0; i < n; i++) {
145             scanf("%d %c %c %d %c %c", &x1, &y1, &z1, &x2, &y2, &z2);
146             y1 -= 'A' - 1;
147             z1 -= '0';
148             y2 -= 'A' - 1;
149             z2 -= '0';
150             a[y1][z1] = x1;
151             a[y2][z2] = x2;
152             vis[y1][z1] = vis[y2][z2] = true;
153             G[x1][x2] = G[x2][x1] = true;
154         }
155         for (i = 1; i < 10; i++) {
156             scanf(" %c %c", &y1, &y2);
157             y1 -= 'A' - 1;
158             y2 -= '0';
159             a[y1][y2] = i;
160             vis[y1][y2] = true;
161         }
162         for (row = i = 1; i < 10; i++) {
163             for (j = 1; j < 10; j++) {
164                 if (a[i][j]) {
165                     k = a[i][j];
166                     Q[row] = k;
167                     Link(row, (i - 1) * 9 + k);
168                     Link(row, 81 + (j - 1) * 9 + k);
169                     Link(row, 162 + ((i - 1) / 3 * 3 + (j - 1) / 3) * 9 + k);
170                     Link(row, 243 + (i - 1) * 9 + j);
171                     row++;
172                 } else {
173                     for (k = 1; k < 10; k++) {
174                         Q[row] = k;
175                         Link(row, (i - 1) * 9 + k);
176                         Link(row, 81 + (j - 1) * 9 + k);
177                         Link(row,
178                                 162 + ((i - 1) / 3 * 3 + (j - 1) / 3) * 9 + k);
179                         Link(row, 243 + (i - 1) * 9 + j);
180                         row++;
181                     }
182                 }
183             }
184         }
185         printf("Puzzle %d\n", ca++);
186         Dance();
187     }
188     return 0;
189 }
原文地址:https://www.cnblogs.com/DrunBee/p/2617287.html