POJ - 3076 Sudoku (舞蹈链模板)

16*16的数独题。网上已经有很多解释了,关于解法推荐博客:https://blog.csdn.net/bl0ss0m/article/details/17918705

这里用来保存舞蹈链模板!


#include 
using namespace std;
typedef long long ll;
const int MAXN = 16*16*16+10;
const int MAXM = 16*16*4+10;
const int MAXNODE=MAXN*MAXM+MAXM;
const int INF = 0x3f3f3f3f;

char s[20][20];
//精确匹配模板
struct DLX{

    int N,M,size;
    int U[MAXNODE],D[MAXNODE],R[MAXNODE],L[MAXNODE];
    int Row[MAXNODE],Col[MAXNODE];

    int H[MAXN],S[MAXM];

    int ansd;//答案用了多少行
    int ansh[MAXN];//保存用了哪一行,用于输出具体答案

    void init(int n,int m){
        N=n;
        M=m;
        for(int i=0;i<=M;i++){
            S[i]=0;
            U[i]=D[i]=i;
            L[i]=i-1;
            R[i]=i+1;
        }
        R[M]=0;
        L[0]=M;
        size=M;
        for(int i=1;i<=N;i++)
            H[i]=-1;
    }

    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 resume(int c){
        for(int i=U[c];i!=c;i=U[i]){
            for(int j=L[i];j!=i;j=L[j])
                ++S[Col[U[D[j]]=D[U[j]]=j]];
        }
        L[R[c]]=R[L[c]]=c;
    }

    bool dance(int d){
        //if(ansd K)return false;
        if(R[0] == 0)return d <= K;

        int c = R[0];
        for(int i = R[0];i != 0;i = R[i])
            if(S[i] < S[c])
                c = i;
        for(int i = D[c];i != c;i = D[i])
        {
            remove(i);
            for(int j = R[i];j != i;j = R[j])remove(j);
            if(dance(d+1))return true;
            for(int j = L[i];j != i;j = L[j])resume(j);
            resume(i);
        }
        return false;
    }
};
//DLX_C g;

//用与数独快速求解填了是哪一个数字
int encode(int a,int b,int c)
{
    return a*256+b*16+c+1;
}
void decode(int code,int &a,int &b,int &c)
{
    code--;
    c=code%16;code/=16;
    b=code%16;code/=16;
    a=code;
}

int main(){

    bool first=true;
    while(scanf("%s",s[0])!=EOF)
    {
        if(first)first=false;
        else printf("\n");

        for(int i=1;i<16;i++)
            scanf("%s",s[i]);
        g.init(16*16*16,16*16*4);

        for(int r=0;r<16;r++)
            for(int c=0;c<16;c++)
                for(int v=0;v<16;v++)
                    if(s[r][c]=='-'||s[r][c]=='A'+v)
                    {
                        int row=encode(r,c,v);
                        g.Link(row,encode(0,r,c));
                        g.Link(row,encode(1,r,v));
                        g.Link(row,encode(2,c,v));
                        g.Link(row,encode(3,(r/4)*4+c/4,v));
                    }
        g.dance(0);
        for(int i=0;i

你可能感兴趣的:(————ACM相关————,——搜索相关——,ACM,-,舞蹈链)