(中等) HDU 4069 Squiggly Sudoku , DLX+精确覆盖。

  Description

  Today we play a squiggly sudoku, The objective is to fill a 9*9 grid with digits so that each column, each row, and each of the nine Connecting-sub-grids that compose the grid contains all of the digits from 1 to 9. 
Left figure is the puzzle and right figure is one solution. 

  Now, give you the information of the puzzle, please tell me is there no solution or multiple solution or one solution.

  还是数独问题,其实和前面的没有什么两样,然后对于每个奇形怪状的9格子,我是用BFS来构造的。。。。。。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>

using namespace std;

const int MaxN=800;
const int MaxM=350;
const int MaxNode=MaxN*MaxM;

int map1[10][10];

struct DLX
{
    int U[MaxNode],D[MaxNode],L[MaxNode],R[MaxNode],col[MaxNode],row[MaxNode];
    int size,n,m;
    int H[MaxN],S[MaxM];
    int ans[100],ans1[100],anst[100];
    int ansnum,depth;

    void init(int _n,int _m)
    {
        ansnum=0;

        n=_n;
        m=_m;

        for(int i=0;i<=m;++i)
        {
            U[i]=D[i]=i;
            L[i]=i-1;
            R[i]=i+1;
            row[i]=0;

            S[i]=0;
        }
        L[0]=m;
        R[m]=0;

        size=m;

        for(int i=1;i<=n;++i)
            H[i]=-1;
    }

    void Link(int r,int c)
    {
        col[++size]=c;
        row[size]=r;
        ++S[c];

        U[size]=U[c];
        D[size]=c;
        D[U[c]]=size;
        U[c]=size;

        if(H[r]==-1)
            H[r]=L[size]=R[size]=size;
        else
        {
            L[size]=L[H[r]];
            R[size]=H[r];
            R[L[H[r]]]=size;
            L[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])
            {
                U[D[j]]=j;
                D[U[j]]=j;
                ++S[col[j]];
            }

        L[R[c]]=R[L[c]]=c;
    }

    void showans()
    {
        for(int i=0;i<depth;++i)
            ans1[(anst[i]-1)/9+1]=(anst[i]-1)%9+1;

        for(int i=1;i<=81;++i)
        {
            cout<<ans1[i];

            if(i%9==0)
                cout<<endl;
        }
    }

    void copyans()
    {
        for(int i=0;i<100;++i)
            anst[i]=ans[i];
    }

    bool Dance(int d)
    {
        if(R[0]==0)
        {
            depth=d;

            if(ansnum)
            {
                ++ansnum;
                return 1;
            }

            ++ansnum;

            copyans();

            return 0;
        }

        int c=R[0];

        for(int i=R[0];i!=0;i=R[i])
            if(S[i]<S[c])
                c=i;

        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 1;

            for(int j=L[i];j!=i;j=L[j])
                resume(col[j]);
        }

        resume(c);

        return 0;
    }

    void display()
    {
        for(int i=R[0];i!=0;i=R[i])
        {
            cout<<i<<‘ ‘;
            for(int j=D[i];j!=i;j=D[j])
                cout<<‘(‘<<j<<‘,‘<<(row[j]-1)%9+1<<‘)‘<<‘ ‘;

            cout<<endl;
        }
    }
};

DLX dlx;
int s[100];

void getchange(int &r,int &c1,int &c2,int &c3,int &c4,int i,int j,int k)
{
    r=(i*9+j)*9+k;
    c1=i*9+j+1;
    c2=i*9+k+81;
    c3=j*9+k+162;
    c4=map1[i][j]*9+k+243;
}

void slove()
{
    int r,c1,c2,c3,c4;

    dlx.init(729,324);

    for(int i=0;i<9;++i)
        for(int j=0;j<9;++j)
            for(int k=1;k<=9;++k)
                if(s[i*9+j]==0 || s[i*9+j]==k)
                {
                    getchange(r,c1,c2,c3,c4,i,j,k);

                    dlx.Link(r,c1);
                    dlx.Link(r,c2);
                    dlx.Link(r,c3);
                    dlx.Link(r,c4);
                }

/*    for(int i=1;i<=81;++i)
        for(int j=1;j<=9;++j)
            dlx.Link(j+(i-1)*9,i);

    for(int i=1;i<=81;++i)
        for(int j=1;j<=9;++j)
            dlx.Link(9*(j-1)+(i-1)%9+1+81*((i-1)/9),i+81);

    for(int i=1;i<=81;++i)
        for(int j=1;j<=9;++j)
            dlx.Link((j-1)*81+i,i+162);

    for(int i=1;i<=3;++i)
        for(int j=1;j<=3;++j)
            for(int k=1;k<=9;++k)
                for(int l=1;l<=3;++l)
                    for(int m=1;m<=3;++m)
                        dlx.Link((i-1)*243+(j-1)*27+k+(l-1)*81+(m-1)*9,(i-1)*27+(j-1)*9+k+243);

    for(int i=0;i<81;++i)
        if(s[i]!=‘.‘)
        {
            dlx.ans1[i+1]=s[i]-‘0‘;

            dlx.remove(i+1);

            for(int j=dlx.D[i+1];j!=i+1;j=dlx.D[j])
            {
                if((dlx.row[j]-1)%9+1==s[i]-‘0‘)
                {
                    for(int k=dlx.R[j];k!=j;k=dlx.R[k])
                        dlx.remove(dlx.col[k]);

                    break;
                }
            }
        }
*/

    dlx.Dance(0);

    int temp=dlx.ansnum;

    if(temp==0)
        cout<<"No solution"<<endl;
    else if(temp==2)
        cout<<"Multiple Solutions"<<endl;
    else
        dlx.showans();
}

const int step[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int kcou;
int lu[10][10][4];

void bfs(int num,int x,int y)
{
    queue <int> que;
    int temp,t1,t2;

    que.push(x*10+y);
    map1[x][y]=num;

    while(!que.empty())
    {
        temp=que.front();
        que.pop();

        t1=temp/10;
        t2=temp%10;

        for(int k=0;k<4;++k)
            if(lu[t1][t2][k] && map1[t1+step[k][0]][t2+step[k][1]]==-1)
            {
                que.push((t1+step[k][0])*10+t2+step[k][1]);
                map1[t1+step[k][0]][t2+step[k][1]]=num;
            }
    }
}

void getmap()
{
    int cou=0;

    for(int i=0;i<9;++i)
        for(int j=0;j<9;++j)
            if(map1[i][j]==-1)
                bfs(cou++,i,j);
}

int main()
{
    ios::sync_with_stdio(false);

    int T,t;
    int fang[4];
    cin>>T;

    for(int cas=1;cas<=T;++cas)
    {
        memset(map1,-1,sizeof(map1));
        memset(s,0,sizeof(s));
        memset(lu,0,sizeof(lu));
        kcou=0;

        for(int i=0;i<9;++i)
            for(int j=0;j<9;++j)
            {
                cin>>t;

                for(int k=0;k<4;++k)
                    if(((t>>(4+k))&1)==0)
                        lu[i][j][k]=1;

                s[i*9+j]=t&15;
            }

        getmap();

        cout<<"Case "<<cas<<‘:‘<<endl;

        slove();
    }

    return 0;
}

时间: 2024-10-07 21:22:40

(中等) HDU 4069 Squiggly Sudoku , DLX+精确覆盖。的相关文章

POJ 3047 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . .

POJ 3076 Sudoku DLX精确覆盖

DLX精确覆盖模版题..... Sudoku Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 4416   Accepted: 2143 Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells are filled with letters from A to P (the fi

POJ 3074 Sudoku DLX精确覆盖

DLX精确覆盖.....模版题 Sudoku Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8336   Accepted: 2945 Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . .

(简单) POJ 3074 Sudoku, DLX+精确覆盖。

Description In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example, . 2 7 3 8 . . 1 . . 1 . . . 6 7 3 5 . . . . . . . 2 9 3 . 5 6 9 2 . 8 . . . . . . . . . . . 6 . 1 7 4 5 . 3 6 4 . . . . . . . 9 5 1

HDU 4069 Squiggly Sudoku Dancing-Links(DLX)+Floodfill

题目大意:..还是数独,不同的是原先的九宫格约束条件变为了给定的任意形状... 我们跑一遍floodfill 得出每一个格子属于哪一个形状 然后就是裸的数独了 这题T<=2500 绝对不能开动态 清则TLE 不清MLE 只能数组模拟 好不容易改完了 尼玛 交上去就WA 最后发现当找到一组解之后 一定要把当前的数独转移到ANS数组中 否则就会被覆盖 导致输出时错误 #include<cstdio> #include<cstring> #include<iostream&g

[DLX+bfs] hdu 4069 Squiggly Sudoku

题意: 给你9*9的矩阵.对于每个数字,能减16代表上面有墙,能减32代表下面有墙... 最后剩下的数字是0代表这个位置数要求,不是0代表这个数已知了. 然后通过墙会被数字分成9块. 然后做数独,这里的数独不是分成9个3*3的小块而是通过墙分成的. 思路: 首先通过数字作出墙. 然后bfs求连通块,dfs也可以.目的是分块. 然后就是dlx数独模板题了. 这里要注意的是如果找到答案2次就说明有多组解了,就应该停止返回了.不然会TLE. 代码: #include"stdio.h" #in

(简单) POJ 3076 Sudoku , DLX+精确覆盖。

Description A Sudoku grid is a 16x16 grid of cells grouped in sixteen 4x4 squares, where some cells are filled with letters from A to P (the first 16 capital letters of the English alphabet), as shown in figure 1a. The game is to fill all the empty g

HDU 4069 Squiggly Sudoku【舞蹈链】【样例坑】

建模思路跟之前的一样,宫的话dfs搜索一下找联通分量就行,好像也没有更好的办法,有的话请评论哈orz --因为舞蹈链一般找到解以后就直接跳出了,所以ans数组就是ans不会再变.但这题让找一下有没有多组解,所以就不能找到一个解后直接跳出.就有一个小坑是都搜完后ans数组可能不是合法ans,所以找到第一个解的时候要单独存一下才能ac --但这个样例就是如果中间不存一下ans数组的话,样例还是能过... --那应该就是正好最后一次枚举的时候找到了这个解?? --不然的话它回溯的时候枚举下一个可能会覆

HDU 3111 Sudoku(精确覆盖)

数独问题,输入谜题,输出解 既然都把重复覆盖的给写成模板了,就顺便把精确覆盖的模板也写好看点吧...赤裸裸的精确覆盖啊~~~水一水~~~然后继续去搞有点难度的题了... 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 #include <string> 7 #includ