spoj 1771 Yet Another N-Queen Problem

 https://www.spoj.pl/problems/NQUEEN/

精確覆蓋,每個格子爲行,行、列、兩條對角線爲列 所以矩陣大小爲 n*n*(6*n-2),dfs的時候當深度大於n就可以退出了

# include <math.h>
# include <stdio.h>
# include <string.h>
# include <stdlib.h>
# include <algorithm>
# include <iostream>
# include <string>
# include <queue>
# include <stack>
# include <map>
# include <set>
# include <vector>
# include <cstring>
# include <list>
# include <ctime>

# define For(i,a)   for((i)=0;i<(a);(i)++)
# define MAX(x,y)   ((x)>(y)? (x):(y))
# define MIN(x,y)   ((x)<(y)? (x):(y))
# define MEM(a)     (memset((a),0,sizeof(a)))
# define MEME(a)    (memset((a),-1,sizeof(a)))
# define MEMX(a)    (memset((a),0x7f,sizeof(a)))

using namespace std;

typedef long long           ll      ;
typedef unsigned long long  ull     ;
typedef unsigned int        uint    ;
typedef unsigned char       uchar   ;
#define N 15000
#define M 500
int U[N],D[N],L[N],R[N];
int C[N],H[2505],S[M],rol[N];
int head,size;
void build(int r,int c)
{
    S[c]++; C[size]=c;
    U[size]=U[c]; D[U[c]]=size;
    D[size]=c; U[c]=size;
    if(H[r]==-1) H[r]=L[size]=R[size]=size;
    else
    {
        L[size]=L[H[r]]; R[L[H[r]]]=size;
        R[size]=H[r]; L[H[r]]=size;
    }
    rol[size]=r;
    size++;
}
void remove(int &c)
{
    R[L[c]]=R[c];
    L[R[c]]=L[c];
    for(int i=D[c];i!=c;i=D[i])
        for(int j=R[i];j!=i;j=R[j])
        {
            D[U[j]]=D[j];
            U[D[j]]=U[j];
            S[C[j]]--;
        }
}
void resume(int &c)
{
    for(int i=U[c];i!=c;i=U[i])
        for(int j=L[i];j!=i;j=L[j])
        {
            D[U[j]]=j;
            U[D[j]]=j;
            S[C[j]]++;
        }
    R[L[c]]=c;
    L[R[c]]=c;
}
int n,ans[2550],b[55],a[2550];
int dfs(int dep)
{
    int i,j,k,c=0,r;
    if(R[head]>n+n||R[head]==head) //if dep>n return ;
    {
        for(i=0;i<dep;i++)
        {
            r=a[ans[i]];
            if(r%n==0) b[r/n]=n;
            else b[r/n+1]=r%n;
        }
        for(i=1;i<=n;i++)
            printf("%d ",b[i]);
        printf("\n");
        return 1;
    }
    for(i=R[head],k=N;i!=head;i=R[i])
        if(S[i]<k&&i<=n+n)
        {
            k=S[i];
            c=i;
        }
    remove(c);
    for(i=D[c];i!=c;i=D[i])
    {
        ans[dep]=rol[i];
        for(j=R[i];j!=i;j=R[j])
            remove(C[j]);
        if(dfs(dep+1)==1)
            return 1;
        for(j=L[i];j!=i;j=L[j])
            resume(C[j]);
    }
    resume(c);
    return 0;
}
int main()
{
    int i,j,k,p;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<=6*n-2;i++)
        {
            R[i]=i+1;L[i]=i-1;
            U[i]=i; D[i]=i;
            S[i]=0;
        }
        R[6*n-2]=0;L[0]=6*n-2;
        MEME(H);
        head=0;size=6*n-1;
        p=1;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&j);
            if(j==0)
            for(k=1;k<=n;k++)
            {
                a[p]=(i-1)*n+k;
                build(p,i);
                build(p,k+n);
                build(p,i+k+n+n-1);
                build(p,k-i+5*n-1);
                p++;
            }
            else
            {
                k=j;
                a[p]=(i-1)*n+k;
                build(p,i);
                build(p,k+n);
                build(p,i+k+n+n-1);
                build(p,k-i+5*n-1);
                p++;
            }
        }
        dfs(0);
    }
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章