hdu 1426——Dancing links

来源:互联网 发布:excel 2013数据有效性 编辑:程序博客网 时间:2024/05/29 14:03
最近在学Dancing links 然后问学长。。。被骂- -
“这么简单都不会啊!!!自己慢慢学。。。什么都要人教的啊。。。那你以后怎么办啊!!!”
好吧~然后。。自学了。。。
自己各种理解后总结的。。。断断续续地花了一个下午。
这个就是以后Dacing links的模板了。。。吼吼吼吼~


<code>

#include<stdio.h>#include<string.h>#include<iostream>using namespace std;#define INF 1000000000const int N = 9;const int head = 0;const int mn = N * N * N *(N * N * N * 4) + N;const int nn = N * N * N + N;int U[mn], D[mn], L[mn], R[mn];int C[mn], Row[mn];int H[nn], Q[nn], S[nn], vis[nn], size;int a[nn][nn], ans[nn][nn];void prepare(int r, int c) {    int i;    for (i = 0; i <= c; i++) {        S[i] = 0; //当前列元素个数        U[i] = D[i] = i;        R[i] = i + 1;        L[i + 1] = i;    }    R[c] = 0;    size = c;    while (r) {        H[r--] = -1;    }}void place(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j, int k) {    r = (i * N + j) * N + k; //行号    //四个列号    c1 = i * N + j + 1; //表示位于第i行j列的格子的列    c2 = N * N + i * N + k; //表示在第i行填k这个数字的列    c3 = 2 * N * N + j * N + k; //表示在第j列填k这个数字的列    c4 = 3 * N * N + ((i / 3) * 3 + j / 3) * N + k; //表示3*3格子中填k这个数字的列}void link(int r, int c) {    size++; //r行c列的值编号为size    C[size] = c;    S[c]++;    Row[size] = r;    D[size] = D[c];    U[D[c]] = size;    U[size] = c;    D[c] = size;    if (H[r] < 0) {        H[r] = size;        L[size] = size;        R[size] = size;    } else {        R[size] = R[H[r]];        L[R[H[r]]] = size;        L[size] = H[r];        R[H[r]] = size;    }}void remove(const int &cur) {    L[R[cur]] = L[cur];    R[L[cur]] = R[cur];    for (int i = D[cur]; i != cur; 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(const int &cur) {    for (int i = U[cur]; i != cur; i = U[i]) {        for (int j = L[i]; j != i; j = L[j]) {            ++S[C[j]];            U[D[j]] = j;            D[U[j]] = j;        }    }    L[R[cur]] = cur;    R[L[cur]] = cur;}bool dance(int cur) {    int i, j, c, temp;    if (R[head] == head) {        for (i = 0; i < cur; i++) {            int x = (Row[Q[i]] - 1) / N / N;            int y = (Row[Q[i]] - 1) / N % N;            ans[x][y] = (Row[Q[i]] - 1) % N + 1;        }        return true;    }    temp = INF;    for (i = R[0]; i != 0; i = R[i])        if (S[i] < temp) {            temp = S[i];            c = i;        }    remove(c);    for (i = D[c]; i != c; i = D[i]) {        Q[cur] = i;        for (j = R[i]; j != i; j = R[j])            remove(C[j]);        if (dance(cur + 1))            return true;        for (j = L[i]; j != i; j = L[j])            resume(C[j]);    }    resume(c);    return false;}int init() {    int i, j, k, r, c1, c2, c3, c4;    char temp[5];    //Input begin    if (scanf("%s", temp) != 1)        return 0;    a[0][0] = (temp[0] == '?' ? 0 : temp[0] - '0');    for (i = 0; i < N; i++)        for (j = 0; j < N; j++) {            if (!i && !j)                continue;            scanf("%s", temp);            a[i][j] = (temp[0] == '?' ? 0 : temp[0] - '0');        }    //Input end    prepare(N * N * N, N * N * 4);    memset(vis, 0, sizeof (vis));    for (i = 0; i < N; i++)        for (j = 0; j < N; j++)            if (a[i][j]) {                place(r, c1, c2, c3, c4, i, j, a[i][j]);                link(r, c1), link(r, c2), link(r, c3), link(r, c4);                vis[c2] = vis[c3] = vis[c4] = 1; //记录下该列是否已经有了            }    for (i = 0; i < N; i++)        for (j = 0; j < N; j++)            if (!a[i][j]) {//对于没有填的进行建图                for (k = 1; k <= N; k++) {                    place(r, c1, c2, c3, c4, i, j, k);                    if (vis[c2] || vis[c3] || vis[c4])                        continue;                    link(r, c1), link(r, c2), link(r, c3), link(r, c4);                }            }    return 1;}void printresult() {    int i, j;    for (i = 0; i < N; i++) {        for (j = 0; j < N; j++) {            if (j) {                printf(" ");            }            printf("%d", ans[i][j]);        }        printf("\n");    }}int main() {    int t = 0;    while (init()) {        dance(head);        if (t++)            printf("\n");        printresult();    }    return 0;}





</code>

原创粉丝点击