zoukankan      html  css  js  c++  java
  • 【POJ 3074】 Sudoku

    【题目链接】

               http://poj.org/problem?id=3074

    【算法】

               将数独问题转化为精确覆盖问题,用Dancing Links求解

               转化方法如下 :

               我们知道,在一个数独中 :

               1.每个格子填且只填一个数

               2.每一行填1-9这九个数

               3.每一列填1-9这九个数

               4.每个格子填1-9这九个数

               对于第一个约束条件,我们用81列,表示是否填入

               对于第二个约束条件,我们每一行用9列,表示这一行是否有1-9

               第三,四个约束条件的处理方式和第二个类似

      【代码】

                

    #include <algorithm>  
    #include <bitset>  
    #include <cctype>  
    #include <cerrno>  
    #include <clocale>  
    #include <cmath>  
    #include <complex>  
    #include <cstdio>  
    #include <cstdlib>  
    #include <cstring>  
    #include <ctime>  
    #include <deque>  
    #include <exception>  
    #include <fstream>  
    #include <functional>  
    #include <limits>  
    #include <list>  
    #include <map>  
    #include <iomanip>  
    #include <ios>  
    #include <iosfwd>  
    #include <iostream>  
    #include <istream>  
    #include <ostream>  
    #include <queue>  
    #include <set>  
    #include <sstream>  
    #include <stdexcept>  
    #include <streambuf>  
    #include <string>  
    #include <utility>  
    #include <vector>  
    #include <cwchar>  
    #include <cwctype>  
    #include <stack>  
    #include <limits.h> 
    using namespace std;
    #define MAXS 250000
    
    int i,j,cnt;
    int mat[800][400];
    char s[100];
    
    struct info
    {
            int pos,val;
    } a[MAXS];
    
    inline int getRow(int pos)
    {    
            return (pos - 1) / 9 + 1;        
    }
    inline int getCol(int pos)
    {
            return (pos - 1) % 9 + 1;        
    }
    inline int getGrid(int pos)
    {
            int x = getRow(pos),y = getCol(pos);
            return (x - 1) / 3 * 3 + (y - 1) / 3 + 1;
    }
    
    struct DancingLinks
    {
            int n,m,step,size;
            int U[MAXS],D[MAXS],L[MAXS],R[MAXS],Row[MAXS],Col[MAXS];
            int H[MAXS],S[MAXS];
            int ans[MAXS];
            inline void init(int _n,int _m)
            {
                    int i;
                    n = _n;
                    m = _m;
                    for (i = 0; i <= m; i++)
                    {
                            S[i] = 0;
                            U[i] = D[i] = i;
                            L[i] = i - 1;
                            R[i] = i + 1;
                    }
                    L[0] = m; R[m] = 0;
                    size = m;
                    for (i = 1; i <= n; i++) H[i] = -1;
            }        
            inline void link(int r,int c)
            {
                    size++;
                    Row[size] = r;
                    Col[size] = c;
                    S[c]++;
                    D[size] = D[c];
                    U[D[c]] = size;
                    U[size] = c;
                    D[c] = size;
                    if (H[r] < 0) L[size] = R[size] = H[r] = size;
                    else
                    {
                            R[size] = R[H[r]];
                            L[R[H[r]]] = size;
                            L[size] = H[r];
                            R[H[r]] = size;
                    }
            }
            inline 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[Col[j]]--;
                            }
                    }
            }
            inline void Resume(int c)
            {
                    int i,j;
                    for (i = U[c]; i != c; i = U[i])
                    {
                            for (j = L[i]; j != i; j = L[j])
                            {
                                    D[U[j]] = j;
                                    U[D[j]] = j;
                                    S[Col[j]]++;
                            }
                    }
                    L[R[c]] = c;
                    R[L[c]] = c;
            }
            inline bool solve(int dep)
            {
                    int i,j,c;
                    if (R[0] == 0)
                    {
                            step = dep;
                            return true;
                    }
                    c = R[0];
                    for (i = R[0]; i != 0; i = R[i])
                    {
                            if (S[i] < S[c])
                                    c = i;
                    }
                    Remove(c);
                    for (i = D[c]; i != c; i = D[i])
                    {
                            ans[dep] = Row[i];
                            for (j = R[i]; j != i; j = R[j])
                                    Remove(Col[j]);
                            if (solve(dep+1)) return true;        
                            for (j = L[i]; j != i; j = L[j])
                                    Resume(Col[j]);
                    }
                    Resume(c);
                    return false;
            }
    } DLX;
    
    int main() 
    {
            
            while (scanf("%s",s+1) && s[1] != 'e')
            {
                    cnt = 1;
                    memset(mat,0,sizeof(mat));
                    for (i = 1; i <= 81; i++)
                    {
                            if (s[i] != '.')
                            {
                                    mat[1][i] = 1;
                                    mat[1][81+(getRow(i)-1)*9+s[i]-'0'] = 1;
                                    mat[1][162+(getCol(i)-1)*9+s[i]-'0'] = 1;
                                    mat[1][243+(getGrid(i)-1)*9+s[i]-'0'] = 1;
                            } else
                            {
                                    for (j = 1; j <= 9; j++)
                                    {
                                            cnt++;
                                            mat[cnt][i] = 1;
                                            mat[cnt][81+(getRow(i)-1)*9+j] = 1;
                                            mat[cnt][162+(getCol(i)-1)*9+j] = 1;
                                            mat[cnt][243+(getGrid(i)-1)*9+j] = 1;
                                            a[cnt] = (info){i,j};
                                    }
                            }
                    }        
                    DLX.init(cnt,324);
                    for (i = 1; i <= cnt; i++)
                    {
                            for (j = 1; j <= 324; j++)
                            {
                                    if (mat[i][j])
                                            DLX.link(i,j);
                            }
                    }
                    DLX.solve(0);
                    for (i = 1; i < DLX.step; i++) s[a[DLX.ans[i]].pos] = '0' + a[DLX.ans[i]].val;
                    for (i = 1; i <= 81; i++) printf("%c",s[i]);
                    printf("
    ");
            }
            
            return 0;
        
    }
  • 相关阅读:
    个人总结05
    微软拼音的用户体验
    个人总结04
    典型用户和用户场景模式
    个人总结03
    个人总结02
    构建之法阅读笔记06
    个人总结01
    学习进度条——第七周
    WebApi学习总结系列第五篇(消息处理管道)
  • 原文地址:https://www.cnblogs.com/evenbao/p/9263156.html
Copyright © 2011-2022 走看看