zoukankan      html  css  js  c++  java
  • UVa 1309 DLX Sudoku

    16×16的数独。

    看白书学的DLX,有些细节还有待消化,贴个模板先。

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <vector>
      5 #include <queue>
      6 using namespace std;
      7 
      8 const int maxn = 16;
      9 const int maxnode = 16384 + 100;
     10 const int maxr = 4096 + 10;
     11 const int maxc = 1024 + 10;
     12 
     13 #define FOR(i,A,s) for(int i = A[s]; i != s; i = A[i])
     14 
     15 struct DLX
     16 {
     17     int n, sz;
     18     int S[maxc];
     19 
     20     int row[maxnode], col[maxnode];
     21     int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
     22 
     23     int ansd, ans[maxr];
     24 
     25     void init(int n)
     26     {
     27         this-> n = n;
     28 
     29         for(int i = 0; i <= n; i++) {
     30             U[i] = D[i] = i; L[i] = i - 1; R[i] = i + 1;
     31         }
     32         L[0] = n; R[n] = 0;
     33 
     34         sz = n + 1;
     35         memset(S, 0, sizeof(S));
     36     }
     37 
     38     void AddRow(int r, vector<int> columns)
     39     {
     40         int first = sz;
     41         for(int i = 0; i < columns.size(); i++)
     42         {
     43             int c = columns[i];
     44             L[sz] = sz - 1; R[sz] = sz + 1; D[sz] = c; U[sz] = U[c];
     45             D[U[c]] = sz; U[c] = sz;
     46             row[sz] = r; col[sz] = c;
     47             S[c]++; sz++;
     48         }
     49         R[sz - 1] = first; L[first] = sz - 1;
     50     }
     51 
     52     void remove(int c)
     53     {
     54         L[R[c]] = L[c];
     55         R[L[c]] = R[c];
     56         FOR(i,D,c)
     57             FOR(j,R,i) { U[D[j]] = U[j]; D[U[j]] = D[j]; --S[col[j]]; }
     58     }
     59 
     60     void restore(int c)
     61     {
     62         FOR(i,U,c)
     63             FOR(j,L,i) { ++S[col[j]]; U[D[j]] = j; D[U[j]] = j; }
     64         L[R[c]] = c;
     65         R[L[c]] = c;
     66     }
     67 
     68     bool dfs(int d)
     69     {
     70         if(R[0] == 0) { ansd = d; return true; }
     71 
     72         int c = R[0];
     73         FOR(i,R,0) if(S[i] < S[c]) c = i;
     74 
     75         remove(c);
     76         FOR(i,D,c)
     77         {
     78             ans[d] = row[i];
     79             FOR(j,R,i) remove(col[j]);
     80             if(dfs(d + 1)) return true;
     81             FOR(j,L,i) restore(col[j]);
     82         }
     83         restore(c);
     84 
     85         return false;
     86     }
     87 
     88     bool solve(vector<int>& v)
     89     {
     90         v.clear();
     91         if(!dfs(0)) return false;
     92         for(int i = 0; i < ansd; i++) v.push_back(ans[i]);
     93         return true;
     94     }
     95 }solver;
     96 
     97 const int SLOT = 0;
     98 const int ROW = 1;
     99 const int COL = 2;
    100 const int SUB = 3;
    101 
    102 int encode(int a, int b, int c) {
    103     return a * 256 + b * 16 + c + 1;
    104 }
    105 
    106 void decode(int code, int& a, int& b, int& c) {
    107     code--;
    108     c = code % 16; code /= 16;
    109     b = code % 16; code /= 16;
    110     a = code % 16;
    111 }
    112 
    113 char G[maxn][maxn + 10];
    114 
    115 bool read()
    116 {
    117     for(int i = 0; i < 16; i++)
    118         if(scanf("%s", G[i]) != 1) return false;
    119     return true;
    120 }
    121 
    122 int main()
    123 {
    124     int kase = 0;
    125     while(read())
    126     {
    127         if(kase++ > 0) puts("");
    128         
    129         solver.init(1024);
    130         for(int r = 0; r < 16; r++)
    131             for(int c = 0; c < 16; c++)
    132                 for(int v = 0; v < 16; v++)
    133                     if(G[r][c] == '-' || G[r][c] == 'A' + v) {
    134                         vector<int> columns;
    135                         //一行完成四个任务
    136                         columns.push_back(encode(SLOT, r, c));
    137                         columns.push_back(encode(ROW, r, v));
    138                         columns.push_back(encode(COL, c, v));
    139                         columns.push_back(encode(SUB, (r/4)*4+c/4, v));
    140                         solver.AddRow(encode(r,c,v), columns);
    141                     }
    142 
    143         vector<int> ans;
    144         solver.solve(ans);
    145 
    146         for(int i = 0; i < ans.size(); i++) {
    147             int r, c, v;
    148             decode(ans[i], r, c, v);
    149             G[r][c] = 'A' + v;
    150         }
    151 
    152         for(int i = 0; i < 16; i++) printf("%s
    ", G[i]);
    153     }
    154 
    155     return 0;
    156 }
    代码君
  • 相关阅读:
    Oracle VM Virtualbox基础知识
    Ubuntu12.10下Python(pyodbc)访问SQL Server解决方案
    制作系统启动盘重装系统
    仪表·使用相关
    Linux·命令收藏
    串口·相关文章
    Linux命令集锦之·字符截取命令
    Linux命令集锦之·正则表达式
    C#·好文分享
    三大操作系统对比使用之·Ubuntu16.04
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4820524.html
Copyright © 2011-2022 走看看