Sudoku HDU

来源:互联网 发布:d3.js 可视化介绍 编辑:程序博客网 时间:2024/06/06 08:56

舞蹈链解决数独问题,也是很经典的一个数独问题
直接套用的书上的模版

//leehaoze#include <iostream>#include <deque>#include <string>#include <vector>#include <queue>#include <cstdio>#include <stack>#include <algorithm>#include <cstring>#include <cctype>#include <cstdio>#include <cmath>#include <cstdlib>using namespace std;const int INF = 1<<29;#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )#define ULL unsigned long longconst int maxn = 4 * 4 * 4 * 4 * 4 * 4;const int maxnode = 4 * 4 * 4 * 4 * 4 * 4;const int maxr = 4 * 4 * 4 * 4 * 4 * 4;struct DLX{    int n, sz;    int S[maxn];    int row[maxnode],col[maxnode];    int L[maxnode],R[maxnode],U[maxnode],D[maxnode];    int ansd,ans[maxr];    void init(int n){        this->n = n;        for(int i = 0;i <= n;++i){            U[i] = i;D[i] = i;L[i]=i-1;R[i] = i+1;        }        R[n] = 0;L[0] = n;        sz =n + 1;        memset(S,0,sizeof S);    }    void addRow(int r,vector<int> columns){        int first =sz;        for (int i = 0; i < columns.size(); ++i) {            int c= columns[i];            L[sz] = sz - 1;            R[sz] = sz + 1;            D[sz] = c;            U[sz] = U[c];            D[U[c]] = sz;            U[c] = sz;            row[sz] = r;            col[sz] = c;            S[c]++;            sz++;        }        R[sz - 1] = first;        L[first] = sz- 1;    }#define FOR(i,A,s)for(int i = A[s]; i != s; i = A[i])    void remove(int c){        L[R[c]] = L[c];        R[L[c]] = R[c];        FOR(i,D,c)        FOR(j,R,i){            U[D[j]] = U[j];            D[U[j]] = D[j];            --S[col[j]];        }    }void restore(int c){    FOR(i,U,c)        FOR(j,L,i){            ++S[col[j]];            U[D[j]] = j;            D[U[j]] = j;        }    L[R[c]] = c;    R[L[c]] = c;}    bool dfs(int d){        if(R[0] == 0){            ansd = d;            return true;        }        int c = R[0];        FOR(i,R,0)if(S[i] < S[c] ) c= i;        remove(c);        FOR(i,D,c){            ans[d] = row[i];            FOR(j,R,i)remove(col[j]);            if(dfs(d+1))return true;            FOR(j,L,i)restore(col[j]);        }        restore(c);        return false;    }    bool solve(vector<int> &v){        v.clear();        if(!dfs(0))return false;        for (int i = 0; i < ansd; ++i) {            v.push_back(ans[i]);        }        return true;    }};DLX solver;const int SLOT = 0;const int ROW = 1;const int COL = 2;const int SUB = 3;int encode(int a,int b,int c){    return a*16+b*4+c+1;}void decode(int code,int &a,int &b,int &c){    code--;    c = code%4; code /= 4;    b = code%4; code /= 4;    a = code;}char puzzle[5][5];void read(){    for (int i = 0; i < 4; ++i) {        scanf("%s",puzzle[i]);    }}int main() {    int T,cases = 1;    scanf("%d",&T);    while(T--) {        read();        solver.init(64);        for (int r = 0; r < 4; ++r)            for (int c = 0; c < 4; ++c)                for (int v = 0; v < 4; ++v)                    if (puzzle[r][c] == '*' || puzzle[r][c] == '1' + v) {                        vector<int> columns;                        columns.push_back(encode(SLOT, r, c));                        columns.push_back(encode(ROW, r, v));                        columns.push_back(encode(COL, c, v));                        columns.push_back(encode(SUB, r / 2 * 2 + c / 2, v));                        solver.addRow(encode(r, c, v), columns);                    }        vector<int> ans;        solver.solve(ans);        for (int i = 0; i < ans.size(); ++i) {            int r,c,v;            decode(ans[i],r,c,v);            puzzle[r][c] = '1' + v;        }        printf("Case #%d:\n",cases++);        for (int i = 0; i < 4; ++i) {            printf("%s\n",puzzle[i]);        }    }    return 0;}
0 0
原创粉丝点击