zoukankan      html  css  js  c++  java
  • HDU 1426 Sudoku Killer

    HDU_1426

    这个题目貌似是可以用深搜做的,但是我实际上是为了演练Dancing Links才选做的这道数独里的简单题。Dancing Links的基本思想就是把图转化成0-1矩阵并最终化归成选出若干行使得每列有且恰有一个1的问题。

    推荐两个文章,一个是momodi写的《Dancing Links在搜索中的应用》,这个在http://wenku.baidu.com/view/4ab7bd00a6c30c2259019eae.html可以下载得到,另外就是Knuth写的《Dancing Links》论文的翻译版。

        如果你看完这些之后向我一样虽然对算法思想有了大概了解,却不知道代码怎么写,尤其是不知道图应该怎么建,或者说建图的代码怎么写,那么可以看看这个解题报告上的代码http://blog.csdn.net/fp_hzq/article/details/6799640,我觉得这份代码还是写的比较清晰的。

    #include<stdio.h>
    #include<string.h>
    #define INF 1000000000
    const int N = 9;
    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], C[mn], X[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;
    c2 = N * N + i * N + k;
    c3 = 2 * N * N + j * N + k;
    c4 = 3 * N * N + ((i / 3) * 3 + j / 3) * N + k;
    }
    void link(int r, int c)
    {
    size ++;
    C[size] = c;
    S[c] ++;
    X[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(int c)
    {
    int i, j;
    L[R[c]] = L[c];
    R[L[c]] = R[c];
    for(i = D[c]; i != c; i = D[i])
    for(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)
    {
    int i, j;
    for(i = U[c]; i != c; i = U[i])
    for(j = L[i]; j != i; j = L[j])
    {
    U[D[j]] = j;
    D[U[j]] = j;
    S[C[j]] ++;
    }
    R[L[c]] = c;
    L[R[c]] = c;
    }
    int dance(int cur)
    {
    int i, j, c, temp;
    if(!R[0])
    {
    for(i = 0; i < cur ;i ++)
    {
    int x = (X[Q[i]] - 1) / N / N;
    int y = (X[Q[i]] - 1) / N % N;
    ans[x][y] = (X[Q[i]] - 1) % N + 1;
    }
    return 1;
    }
    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 1;
    for(j = L[i]; j != i; j = L[j])
    resume(C[j]);
    }
    resume(c);
    return 0;
    }
    int init()
    {
    int i, j, k, r, c1, c2, c3, c4;
    char temp[5];
    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');
    }
    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(0);
    if(t ++)
    printf("\n");
    printresult();
    }
    return 0;
    }


  • 相关阅读:
    Poj3678:Katu Puzzle
    2-SAT
    Bzoj3238: [Ahoi2013]差异
    expressJS
    expressJS
    expressJS
    [转]View属性 之 paddingStart & paddingEnd
    在Activity之间使用Intent传值和Bundle传值的区别和方式
    [转]Java初始化顺序总结
    final关键字修饰的变量
  • 原文地址:https://www.cnblogs.com/staginner/p/2204955.html
Copyright © 2011-2022 走看看