poj 3074 Sudoku

题意:解出9*9数独


思路:和poj 3076一样,只不过编码函数有点不同,依然使用舞蹈链


题目链接:http://poj.org/problem?id=3074


#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;

const int maxn=400;
const int maxnode=3000;
const int maxr=1000;
struct DLX
{
    int n,sz;
    int s[maxn];
    int row[maxnode],col[maxnode];
    int r[maxnode],l[maxnode],u[maxnode],d[maxnode];
    int ansd,ans[maxr];

    void init(int n)
    {
        this->n=n;
        for(int i=0;i<=n;i++)
        {
            l[i]=i-1,r[i]=i+1,u[i]=d[i]=i;
        }
        l[0]=n,r[n]=0;
        sz=n+1;
        memset(s,0,sizeof(s));
    }

    void addrow(int R,const vector<int> &v)
    {
        int first=sz;
        for(int i=0;i<(int)v.size();i++)
        {
           int c=v[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;
    }

    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 Restore(int c)
    {
        for(int i=u[c];i!=c;i=u[i])
        {
            for(int j=l[i];j!=i;j=l[j])
            {
                ++s[col[j]];
                u[d[j]]=j,d[u[j]]=j;
            }
        }
        l[r[c]]=c;
        r[l[c]]=c;
    }

    bool dfs(int cur)
    {
        if(r[0]==0)
        {
            ansd=cur;
            return true;
        }

        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[cur]=row[i];
            for(int j=r[i];j!=i;j=r[j]) Remove(col[j]);
            if(dfs(cur+1)) return true;
            for(int j=l[i];j!=i;j=l[j]) 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 dlx;

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*81+b*9+c+1;
}

void decode(int code,int &a,int &b,int &c)
{
    code--;
    c=code%9,code/=9;
    b=code%9,code/=9;
    a=code;
}

char s[100],a[10][10];
int main(void)
{
    vector<int> v1;
    while(scanf("%s",s),s[0]!='e')
    {
        dlx.init(324);
        int cnt=0;
        for(int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
                a[i][j]=s[cnt++];
            a[i][9]='\0';
        }
        for(int r=0;r<9;r++)
        {
            for(int c=0;c<9;c++)
            {
                for(int v=0;v<9;v++)
                {
                    if(a[r][c]=='.'||a[r][c]=='1'+v)
                    {
                        v1.clear();
                        v1.push_back(encode(slot,r,c));
                        v1.push_back(encode(row,r,v));
                        v1.push_back(encode(col,c,v));
                        v1.push_back(encode(sub,(r/3)*3+c/3,v));
                        dlx.addrow(encode(r,c,v),v1);
                    }
                }
            }
        }
        v1.clear();
        dlx.solve(v1);
        int r,c,v;
        for(int i=0;i<(int)v1.size();i++)
        {
            decode(v1[i],r,c,v);
            a[r][c]='1'+v;
        }
        for(int i=0;i<9;i++)
            printf("%s",a[i]);
        printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值