• SPOJ 1771 Yet Another NQueen Problem


    SPOJ_1771

        通过这个题目进一步训练了Dancing Links解决N皇后问题的技巧。

    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    #define INF 1000000000
    const int MAXN = 50;
    const int MAXmn = MAXN * MAXN * 4 + MAXN * 6 + MAXN;
    const int MAXnn = MAXN * 6 + MAXN;
    int N, size;
    int U[MAXmn], D[MAXmn], L[MAXmn], R[MAXmn], H[MAXmn], C[MAXmn], X[MAXmn];
    int Q[MAXnn], S[MAXnn], x[MAXnn], y[MAXnn], r[MAXnn], visc[MAXnn];
    int cmp(const void *_p, const void *_q)
    {
    int *p = (int *)_p;
    int *q = (int *)_q;
    return x[*p] - x[*q];
    }
    void prepare(int r, int c)
    {
    int i, j;
    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)
    {
    r = (i - 1) * N + j;
    c1 = j;
    c2 = N + i;
    c3 = N * 3 + i - j;
    c4 = N * 4 + i + j - 2;
    }
    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] = L[size] = R[size] = size;
    else
    {
    R[size] = R[H[r]];
    L[R[H[r]]] = size;
    L[size] = H[r];
    R[H[r]] = size;
    }
    }
    int init()
    {
    int i, j, r, c1, c2, c3, c4;
    if(scanf("%d", &N) != 1)
    return 0;
    prepare(N * N, N * 6 - 2);
    memset(visc, 0, sizeof(visc));
    for(i = 1; i <= N; i ++)
    {
    scanf("%d", &j);
    if(j)
    {
    place(r, c1, c2, c3, c4, i, j);
    link(r, c1), link(r, c2), link(r, c3), link(r, c4);
    visc[c1] = visc[c2] = visc[c3] = visc[c4] = 1;
    }
    }
    for(i = 1; i <= N; i ++)
    for(j = 1; j <= N; j ++)
    {
    place(r, c1, c2, c3, c4, i, j);
    if(visc[c1] || visc[c2] || visc[c3] || visc[c4])
    continue;
    link(r, c1), link(r, c2), link(r, c3), link(r, c4);
    }
    return 1;
    }
    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])
    {
    S[C[j]] ++;
    U[D[j]] = j;
    D[U[j]] = j;
    }
    L[R[c]] = c;
    R[L[c]] = c;
    }
    int dance(int cur)
    {
    int i, j, c, temp;
    if(cur >= N)
    {
    for(i = 0; i < cur; i ++)
    {
    x[i] = (X[Q[i]] - 1) / N + 1;
    y[i] = (X[Q[i]] - 1) % N + 1;
    }
    return 1;
    }
    if(!R[0])
    return 0;
    temp = INF;
    for(i = R[0]; i <= N; 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;
    }
    void printresult()
    {
    int i;
    for(i = 0; i < N; i ++)
    r[i] = i;
    qsort(r, N, sizeof(r[0]), cmp);
    for(i = 0; i < N; i ++)
    {
    if(i)
    printf(" ");
    printf("%d", y[r[i]]);
    }
    printf("\n");
    }
    int main()
    {
    while(init())
    {
    if(dance(0))
    printresult();
    }
    return 0;
    }


  • 相关阅读:
    树形dp入门
    D. Kilani and the Game(多源BFS)
    C. Ayoub and Lost Array
    poj3254(状压dp)
    CodeForces
    链式前项星(模板)
    “东信杯”广西大学第一届程序设计竞赛(同步赛)H
    最小生成树kruskal模板
    hdu-4763(kmp+拓展kmp)
    poj-3080(kmp+暴力枚举)
  • 原文地址:https://www.cnblogs.com/staginner/p/2208047.html
Copyright © 2020-2023  润新知