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

题目大意:。。还是数独,不同的是原先的九宫格约束条件变为了给定的任意形状。。。

我们跑一遍floodfill 得出每一个格子属于哪一个形状

然后就是裸的数独了

这题T<=2500 绝对不能开动态 清则TLE 不清MLE 只能数组模拟

好不容易改完了 尼玛 交上去就WA

最后发现当找到一组解之后 一定要把当前的数独转移到ANS数组中 否则就会被覆盖 导致输出时错误


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; 
struct abcd{
    int l,r,u,d;
    int x,y,num;
    int bottom;
    void del();
    void restore();
}table[4000];
int head,tot,stack[4000],top;
int m,n,cnt,flag,map[9][9],belong[9][9],input[9][9],ans[9][9];
void del_column(int pos)
{
    int i,j;
    for(i=table[pos].u;i;i=table[i].u)
    {
        for(j=table[i].l;j;j=table[j].l)
            table[j].del();
        for(j=table[i].r;j;j=table[j].r)
            table[j].del();
        table[i].del();
    }
    table[pos].del();
}
inline void output()
{
    int i,j;
    for(i=0;i<9;i++)
    {
        for(j=0;j<9;j++)
            putchar(ans[i][j]+'0');
        putchar('\n');
    }
}
void DLX()
{
    if(!table[head].r)
    {
        memcpy(ans,map,sizeof ans);
        flag++;
        return ;
    }
    int i,mini,bottom=top,minnum=0x7fffffff;
    for(i=table[head].r;i;i=table[i].r)
        if(table[i].x<minnum)
            minnum=table[i].x,mini=i;
    for(i=table[mini].u;i;i=table[i].u)
    {
        int x=table[i].x,y=table[i].y,num=table[i].num;
        map[x][y]=num;

        del_column(x*9+y+2                      );
        del_column(81+x*9+num+1                  );
        del_column(162+y*9+num+1              );
        del_column(243+(belong[x][y])*9+num+1 );
        
        DLX();
        while(top!=bottom)
            table[stack[top--]].restore();
        if(flag>=2)
            return ;
    }
}
int New(int L,int R,int U,int D,int X,int Y,int Num)
{
    ++tot;
    table[tot].l=L;if(L)table[L].r=tot;
    table[tot].r=R;if(R)table[R].l=tot;
    table[tot].u=U;if(U)table[U].d=tot;
    table[tot].d=D;if(D)table[D].u=tot;
    table[tot].x=X;table[tot].y=Y;table[tot].num=Num;
    table[tot].bottom=D;
    if(table[tot].bottom)
        table[table[tot].bottom].x++;
    return tot;
}
void abcd :: del()
{
    if(l)table[l].r=r;
    if(r)table[r].l=l;
    if(u)table[u].d=d;
    if(d)table[d].u=u;
    if(bottom)
        table[bottom].x--;
    stack[++top]=this-table;
}
void abcd :: restore()
{
    if(l)table[l].r=this-table;
    if(r)table[r].l=this-table;
    if(u)table[u].d=this-table;
    if(d)table[d].u=this-table;
    if(bottom)
        table[bottom].x++;
}
void add(int x,int y,int num)
{
    int last=0,temp;
    temp=x*9+y+2                   ,last=New(last,0,table[temp].u,temp,x,y,num);
    temp=81+x*9+num+1               ,last=New(last,0,table[temp].u,temp,x,y,num);
    temp=162+y*9+num+1               ,last=New(last,0,table[temp].u,temp,x,y,num);
    temp=243+(belong[x][y])*9+num+1,last=New(last,0,table[temp].u,temp,x,y,num);
}
void initialize()
{
    int i;
    
    top=0;flag=0;cnt=0;tot=0;
    head=New(0,0,0,0,0,0,0);
    memset(map,-1,sizeof map);
    for(i=1;i<=81*4;i++)
        New(i,0,0,0,0,0,0);
}
void floodfill(int x,int y)
{
    if(~map[x][y])
        return ;
    belong[x][y]=cnt;
    map[x][y]=input[x][y]&15;
    if(~input[x][y]&16 )floodfill(x-1,y);
    if(~input[x][y]&32 )floodfill(x,y+1);
    if(~input[x][y]&64 )floodfill(x+1,y);
    if(~input[x][y]&128)floodfill(x,y-1);
}
int main()
{
    int T,i,j,k,x,Case=0;
     
    //freopen("sudoku.in","r",stdin);
    //freopen("sudoku.out","w",stdout);
    
    for(cin>>T;T;T--)
    {
        initialize();
        printf("Case %d:\n",++Case);
        
        for(i=0;i<9;i++)
            for(j=0;j<9;j++)
                scanf("%d",&input[i][j]);
                
        for(i=0;i<9;i++)
            for(j=0;j<9;j++)
                if(map[i][j]==-1)
                    floodfill(i,j),cnt++;

        for(i=0;i<9;i++)
            for(j=0;j<9;j++)
                if(map[i][j])
                    add(i,j,map[i][j]);
                else
                    for(k=1;k<=9;k++)
                        add(i,j,k);
        DLX();
        if(!flag)
            puts("No solution");
        else if(flag==1)
            output();
        else
            puts("Multiple Solutions");
    }
}



你可能感兴趣的:(HDU,数独,dlx,HDU4069,Dancing-Links)