您的位置:首页 > 其它

DLX(n皇后)spoj1771

2014-11-16 14:09 579 查看

1771. Yet Another N-Queen Problem

Problem code: NQUEEN

After solving
Solution to the n Queens Puzzle by constructing, LoadingTime wants to solve a harder version of the N-Queen Problem. Some queens have been set on particular locations on the board in this problem. Can you help him??

Input

The input contains multiple test cases. Every line begins with an integer N (N<=50), then N integers followed, representing the column number of the queen in each rows. If the number is 0, it means no queen has been set on this row. You can assume there
is at least one solution.

Output

For each test case, print a line consists of N numbers separated by spaces, representing the column number of the queen in each row. If there are more than one answer, print any one of them.

Example

Input:
4 0 0 0 0
8 2 0 0 0 4 0 0 0

Output:
2 4 1 3
2 6 1 7 4 8 3 5


#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
const int maxn=3333;
const int maxnode=777777;
int path[maxn];
int N,X[maxn],Y[maxn];
bool vis[maxn];
struct DLX
{
    int n,m,size;
    int U[maxnode],D[maxnode],L[maxnode],R[maxnode];
    int H[maxn],S[maxn];
    int row[maxnode],col[maxnode];
    int ansd,ans[maxn];
    void init(int N,int M)
    {
        n=N,m=M;
        for(int i=0;i<=m;i++)
        {
            U[i]=D[i]=i;
            L[i]=i-1;
            R[i]=i+1;
            S[i]=0;
        }
        L[0]=m,R[m]=0;
        size=m;
        memset(H,-1,sizeof(H));
    }
    void Link(int r,int c)
    {
        ++S[col[++size]=c];
        row[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;
        }
    }
    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[col[j]];
            }
        }
    }
    void restore(int c)
    {
        for(int i=U[c];i!=c;i=U[i])
        {
            for(int j=L[i];j!=i;j=L[j])
            {
                U[D[j]]=D[U[j]]=j;
                ++S[col[j]];
            }
        }
        L[R[c]]=R[L[c]]=c;
    }
    bool Dance(int d)
    {
        if(d>=N)
        {
            ansd=d;
            for(int i=0;i<d;i++)
                path[X[ans[i]]]=Y[ans[i]];
            return true;
        }
        if(R[0]==0)
            return false;
        int c=R[0];
        for(int i=R[0];i;i=R[i])
            if(i<=N)
            {
                if(S[i]<S[c])c=i;
            }
            else break;
        remove(c);
        for(int i=D[c];i!=c;i=D[i])
        {
            ans[d]=row[i];
            for(int j=R[i];j!=i;j=R[j])remove(col[j]);
            if(Dance(d+1))return true;
            for(int j=L[i];j!=i;j=L[j])restore(col[j]);
        }
        restore(c);
        return false;
    }
}dlx;
int main()
{
    while(scanf("%d",&N)!=EOF)
    {
        memset(vis,0,sizeof(vis));
        int p1,p2,p3,p4,cnt=1;
        dlx.init(N*N,N*6-2);
        for(int i=1;i<=N;i++)
        {
            int x;
            scanf("%d",&x);
            if(!x)continue;
            p1=x,p2=N+i,p3=N+N+i-x+N,p4=N+N+N+N+i+x-2;
            vis[p1]=vis[p2]=vis[p3]=vis[p4]=true;
            dlx.Link(cnt,p1);
            dlx.Link(cnt,p2);
            dlx.Link(cnt,p3);
            dlx.Link(cnt,p4);
            X[cnt]=i,Y[cnt]=x;
            cnt++;
        }
        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=N;j++)
            {
                p1=j,p2=N+i,p3=N+N+i-j+N,p4=N+N+N+N+i+j-2;
                if(vis[p1]||vis[p2]||vis[p3]||vis[p4])continue;
                dlx.Link(cnt,p1);
                dlx.Link(cnt,p2);
                dlx.Link(cnt,p3);
                dlx.Link(cnt,p4);
                X[cnt]=i,Y[cnt]=j;
                cnt++;
            }
        }
        dlx.Dance(0);
        for(int i=1;i<N;i++)
            printf("%d ",path[i]);
        printf("%d\n",path
);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: