poj3076 Sudoku--舞蹈链数独

来源:互联网 发布:淘宝修真记全集下载 编辑:程序博客网 时间:2024/06/10 03:56

原题链接:http://poj.org/problem?id=3076


题意:一个数独模板题,16*16的数独。


#define _CRT_SECURE_NO_DEPRECATE #include<iostream>#include<vector>#include<cstring>#include<queue>#include<stack>#include<algorithm>#include<cmath>#define INF 99999999#define eps 0.0001using namespace std;const int MAXC = 16 * 16 * 4 + 10;const int MAXR = 16 * 16 * 16 + 10;const int MAXN = MAXC*MAXR + 10;int cnt;char s[20][20];int U[MAXN], D[MAXN], R[MAXN], L[MAXN];int C[MAXN], M[MAXN];int H[MAXR];int S[MAXC];int ans[16 * 16 + 1000];void init(int n){for (int i = 0; i <= n; i++){U[i] = D[i] = i;L[i] = i - 1;R[i] = i + 1;S[i] = 0;}R[n] = 0;L[0] = n;S[0] = INF + 1;cnt = n + 1;memset(H, 0, sizeof(H));}void link(int r, int c){M[cnt] = r;C[cnt] = c;U[cnt] = U[c];D[cnt] = c;D[U[c]] = cnt;U[c] = cnt;if (H[r] == 0)H[r] = L[cnt] = R[cnt] = cnt;else{L[cnt] = L[H[r]];R[cnt] = H[r];R[L[H[r]]] = cnt;L[H[r]] = cnt;}S[c]++;cnt++;}void remove(int c){L[R[c]] = L[c];R[L[c]] = R[c];for (int i = D[c]; i != c; i = D[i]){for (int j = R[i]; j != i; j = R[j]){U[D[j]] = U[j];D[U[j]] = D[j];S[C[j]]--;}}}void resume(int c){L[R[c]] = c;R[L[c]] = c;for (int i = U[c]; i != c; i = U[i]){for (int j = L[i]; j != i; j = L[j]){U[D[j]] = j;D[U[j]] = j;S[C[j]]++;}}}bool dance(int k){if (R[0] == 0){sort(ans, ans + 16 * 16);int p = 0;for (int i = 0; i < 16; i++){for (int j = 0; j < 16; j++){int num = ans[p++];num = num - (i * 16 + j) * 16 - 1;printf("%c", num + 'A');}printf("\n");}printf("\n");return true;}int c;int t = INF;for (int i = R[0]; i != 0; i = R[i]){if (t > S[i]){t = S[i];c = i;}}remove(c);for (int i = D[c]; i != c; i = D[i]){ans[k] = M[i];for (int j = R[i]; j != i; j = R[j])remove(C[j]);if (dance(k + 1))return true;for (int j = L[i]; j != i; j = L[j])resume(C[j]);}resume(c);return false;}void build(){init(16 * 16 * 4);for (int i = 0; i < 16; i++){for (int j = 0; j < 16; j++){int base = (i * 16 + j) * 16;if (s[i][j] == '-'){for (int k = 1; k <= 16; k++){int r = base + k;link(r, i * 16 + k);link(r, 16 * 16 + j * 16 + k);link(r, 16 * 16 * 2 + (i / 4 * 4 + j / 4) * 16 + k);link(r, 16 * 16 * 3 + i * 16 + j + 1);}}else{int k = s[i][j] - 'A' + 1;int r = base + k;link(r, i * 16 + k);link(r, 16 * 16 + j * 16 + k);link(r, 16 * 16 * 2 + (i / 4 * 4 + j / 4) * 16 + k);link(r, 16 * 16 * 3 + i * 16 + j + 1);}}}}int main(){while (~scanf("%s", s[0])){for (int i = 1; i < 16; i++)scanf("%s", s[i]);build();dance(0);}return 0;}




1 0