HDOJ 4069 Squiggly Sudoku 精确覆盖+搜索

来源:互联网 发布:大革命和枭雄优化 编辑:程序博客网 时间:2024/06/08 06:27
//HDOJ 4069 Squiggly Sudoku 精确覆盖+搜索/*题意:数独变形   9块弯弯曲曲的区域 每块有9个小格  往这81个格子里面填写1-9的数字,使得每行,每列,每个区域都含有1、2、3...9思路:先搜索标记出每一块 再精确覆盖*/#include<iostream>#include<stdio.h>#include<string.h>#include<queue>using namespace std;#define INF 0x7FFFFFFF#define N 750#define M 350#define V N*Mint n, m, size, row, cnt;int L[V], R[V], U[V], D[V], C[V] , X[V];int S[M], Q[N] , H[N];int s[10][10];bool map[100][100],vis[N];int dir[][2] = {0,-1,1,0,0,1,-1,0};int bx[] = {128,64,32,16};int color[10][10],ans[N];struct node{    int x,y;};void init(){    int i;    for (i = 0; i <= m; i++){        S[i] = 0;        L[i + 1] = i;        R[i] = i + 1;        U[i] = D[i] = i;    }    R[m] = 0;    size = m + 1;}void remove(int c){    int i, j;    R[L[c]] = R[c];    L[R[c]] = L[c];    for (i = D[c]; i != c; i = D[i]){        for (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){    int i, j;    R[L[c]] = c;    L[R[c]] = c;    for (i = D[c]; i != c; i = D[i]){        for (j = R[i]; j != i; j = R[j]){            U[D[j]] = j;            D[U[j]] = j;            S[C[j]]++;        }    }}void Link(int r, int c){    D[size] = D[c];    U[size] = c;    U[D[c]] = size;    D[c] = size;    if (H[r] < 0)        H[r] = L[size] = R[size] = size;    else{        L[size] = H[r];        R[size] = R[H[r]];        L[R[H[r]]] = size;        R[H[r]] = size;    }    S[c]++;    C[size] = c;    X[size++] = r;}bool Dance(){    int i, j, c, temp;    if (R[0] == 0){        ++cnt;        if(cnt == 1){            for(i = j = 1; i <= row; ++i)                if(vis[i])                    ans[j++] = Q[i];        }        return cnt > 1;    }    for (temp = INF, i = R[0]; i; i = R[i]){        if (S[i] < temp){            c = i;            temp = S[i];        }    }    remove(c);    for (i = D[c]; i != c; i = D[i]){        vis[X[i]] = true;        for (j = R[i]; j != i; j = R[j])            remove(C[j]);        if (Dance())            return true;        for (j = L[i]; j != i; j = L[j])            resume(C[j]);        vis[X[i]] = false;    }    resume(c);    return false;}bool check(int x,int y){    if(x>=1 && x<=9 && y>=1 && y<=9)        return true;    return false;}void Init(){    int i,j,k,x,y;    memset(map,false,sizeof(map));    for(i = 1; i <= 9; ++i){        for(j = 1; j <= 9; ++j){                   scanf("%d",&s[i][j]);            for(k = 0; k < 4; ++k){                if(s[i][j] >= bx[k])                    s[i][j] -= bx[k];                else{                    x = i + dir[k][0];                    y = j + dir[k][1];                    if(check(x,y))                        map[(i-1)*9+j][(x-1)*9+y] = true;                }            }        }    }}void bfs(int x,int y,int c){    int k;    queue<node>Q;    node p,q;    p.x = x;    p.y = y;    Q.push(p);    while(!Q.empty()){        q = Q.front();        Q.pop();        for(k = 0; k < 4; ++k){            p.x = q.x + dir[k][0];            p.y = q.y + dir[k][1];            if(check(p.x,p.y) && map[(q.x-1)*9+q.y][(p.x-1)*9+p.y] && color[p.x][p.y]==-1){                color[p.x][p.y] = c;                Q.push(p);            }        }    }}void Color(){    int i,j,num = 0;    memset(color,-1,sizeof(color));    for(i = 1; i <= 9; ++i)        for(j = 1; j <= 9; ++j){            if(color[i][j] == -1){                color[i][j] = num;                bfs(i,j,num);                num++;            }        }}void Build(){    init();    int i,j,k;    row = 0;    for(i = 1; i <= 9; ++i){        for(j = 1; j <= 9; ++j){            if(s[i][j] == 0){                for(k = 1; k <= 9; ++k){                    H[++row] = -1;                    Q[row] = k;                    Link(row,(i-1)*9+k);                    Link(row,81+(j-1)*9+k);                    Link(row,162+color[i][j]*9+k);                    Link(row,243+(i-1)*9+j);                }            }            else{                H[++row] = -1;                k = s[i][j];                Q[row] = k;                Link(row,(i-1)*9+k);                Link(row,81+(j-1)*9+k);                Link(row,162+color[i][j]*9+k);                Link(row,243+(i-1)*9+j);            }        }    }}int main(){    int T,i,j,num,ca = 1;    int x,y;    m = 324;    scanf("%d",&T);    while(T--){        Init();        Color();        Build();        memset(vis,false,sizeof(vis));        cnt = 0;        Dance();        printf("Case %d:\n",ca++);        if(cnt == 0)            puts("No solution");        else if(cnt > 1)            puts("Multiple Solutions");        else{            num = 1;            for(i = 1; i <= 9; ++i){                for(j = 1; j <= 9; ++j){                    printf("%d",ans[num]);                    if(num%9 == 0)                        puts("");                    num++;                }            }        }    }    return 0;}

原创粉丝点击