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

    【题目链接】

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

    【算法】

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

    【代码】

               

    #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 100000
    
    struct info
    {
            int pos,val;
    } a[MAXS];
    
    int i,j,cnt;
    int mat[5000][2000];
    char s[300];
    
    inline int getRow(int pos)
    {
            return (pos - 1) / 16 + 1;        
    }
    inline int getCol(int pos)
    {
            return (pos - 1) % 16 + 1;        
    }
    inline int getGrid(int pos)
    {
            int x = getRow(pos),y = getCol(pos);
            return (x - 1) / 4 * 4 + (y - 1) / 4 + 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) != EOF)
            {
                    cnt = 1;
                    memset(mat,0,sizeof(mat));
                    for (i = 1; i < 16; i++) scanf("%s",s+i*16+1);
                    for (i = 1; i <= 256; i++)
                    {
                            if (s[i] != '-')
                            {
                                    mat[1][i] = 1;
                                    mat[1][256+(getRow(i)-1)*16+s[i]-'A'+1] = 1;
                                    mat[1][512+(getCol(i)-1)*16+s[i]-'A'+1] = 1;
                                    mat[1][768+(getGrid(i)-1)*16+s[i]-'A'+1] = 1;
                            } else
                            {
                                    for (j = 1; j <= 16; j++)
                                    {
                                            cnt++;
                                            mat[cnt][i] = 1;
                                            mat[cnt][256+(getRow(i)-1)*16+j] = 1;
                                            mat[cnt][512+(getCol(i)-1)*16+j] = 1;
                                            mat[cnt][768+(getGrid(i)-1)*16+j] = 1;
                                            a[cnt] = (info){i,j};
                                    }
                            }
                    }
                    DLX.init(cnt,1024);
                    for (i = 1; i <= cnt; i++)
                    {
                            for (j = 1; j <= 1024; 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] = 'A' + a[DLX.ans[i]].val - 1;
                    for (i = 1; i <= 256; i++)
                    {
                            printf("%c",s[i]);
                            if (i % 16 == 0) printf("
    ");
                    }
                    printf("
    ");
            }
            
            return 0;
        
    }
  • 相关阅读:
    shell学习(11)- seq
    bash快捷键光标移动到行首行尾等
    shell学习(10)- if的使用
    Python 执行 Shell 命令
    查看 jar 包加载顺序
    Linux 中的 sudoers
    Ubuntu 开机启动程序
    指定 Docker 和 K8S 的命令以及用户
    Spark on K8S(Standalone)
    Spark on K8S (Kubernetes Native)
  • 原文地址:https://www.cnblogs.com/evenbao/p/9263489.html
Copyright © 2011-2022 走看看