• 【HDOJ】3909 Sudoku


    DLX的应用,基本题,注意maxnode开大点儿。

      1 /* 3909 */
      2 #include <iostream>
      3 #include <string>
      4 #include <map>
      5 #include <queue>
      6 #include <set>
      7 #include <stack>
      8 #include <vector>
      9 #include <deque>
     10 #include <algorithm>
     11 #include <cstdio>
     12 #include <cmath>
     13 #include <ctime>
     14 #include <cstring>
     15 #include <climits>
     16 #include <cctype>
     17 #include <cassert>
     18 #include <functional>
     19 #include <iterator>
     20 #include <iomanip>
     21 using namespace std;
     22 //#pragma comment(linker,"/STACK:102400000,1024000")
     23 
     24 #define sti                set<int>
     25 #define stpii            set<pair<int, int> >
     26 #define mpii            map<int,int>
     27 #define vi                vector<int>
     28 #define pii                pair<int,int>
     29 #define vpii            vector<pair<int,int> >
     30 #define rep(i, a, n)     for (int i=a;i<n;++i)
     31 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     32 #define clr                clear
     33 #define pb                 push_back
     34 #define mp                 make_pair
     35 #define fir                first
     36 #define sec                second
     37 #define all(x)             (x).begin(),(x).end()
     38 #define SZ(x)             ((int)(x).size())
     39 #define lson            l, mid, rt<<1
     40 #define rson            mid+1, r, rt<<1|1
     41 
     42 typedef struct DLX {
     43     static const int maxc = 4*16*16+5;
     44     static const int maxr = 16*16*16+5;
     45     static const int maxnode = 16*16*16*5+5;
     46     
     47     int n, sz;
     48     int S[maxc];
     49     
     50     int row[maxnode], col[maxnode];
     51     int L[maxnode], R[maxnode], U[maxnode], D[maxnode];
     52     
     53     int ansd, cnt, ans[maxr], ans_[maxr];
     54     
     55     void init(int n_) {
     56         cnt = 0;
     57         n = n_;
     58         
     59         rep(i, 0, n+1) {
     60             L[i] = i-1;
     61             R[i] = i+1;
     62             U[i] = i;
     63             D[i] = i;
     64         }
     65         
     66         L[0] = n;
     67         R[n] = 0;
     68         
     69         sz = n+1;
     70         memset(S, 0, sizeof(S));
     71     }
     72     
     73     void addRow(int r, vi columns) {
     74         int first = sz;
     75         int size = SZ(columns);
     76         
     77         rep(i, 0, size) {
     78             int c = columns[i];
     79             
     80             L[sz] = sz-1;
     81             R[sz] = sz+1;
     82             
     83             D[sz] = c;
     84             U[sz] = U[c];
     85             D[U[c]] = sz;
     86             U[c] = sz;
     87             
     88             row[sz] = r;
     89             col[sz] = c;
     90             
     91             ++S[c];
     92             ++sz;
     93         }
     94         
     95         R[sz - 1] = first;
     96         L[first] = sz - 1;
     97     }
     98     
     99     void remove(int c) {
    100         L[R[c]] = L[c];
    101         R[L[c]] = R[c];
    102         for (int i=D[c]; i!=c; i=D[i]) {
    103             for (int j=R[i]; j!=i; j=R[j]) {
    104                 U[D[j]] = U[j];
    105                 D[U[j]] = D[j];
    106                 --S[col[j]];
    107             }
    108         }
    109     }
    110     
    111     void restore(int c) {
    112         L[R[c]] = c;
    113         R[L[c]] = c;
    114         for (int i=D[c]; i!=c; i=D[i]) {
    115             for (int j=R[i]; j!=i; j=R[j]) {
    116                 U[D[j]] = j;
    117                 D[U[j]] = j;
    118                 ++S[col[j]];
    119             }
    120         }
    121     }
    122     
    123     bool dfs(int d) {
    124         if (R[0] == 0) {
    125             ansd = d;
    126             ++cnt;
    127             rep(i, 0, ansd)
    128                 ans_[i] = ans[i];
    129             return cnt>1;
    130         }
    131         
    132         int c = R[0];
    133         for (int i=R[0]; i!=0; i=R[i]) {
    134             if (S[i] < S[c])
    135                 c = i;
    136         }
    137         
    138         remove(c);
    139         for (int i=D[c]; i!=c; i=D[i]) {
    140             ans[d] = row[i];
    141             for (int j=R[i]; j!=i; j=R[j]) {
    142                 remove(col[j]);
    143             }
    144             if (dfs(d + 1))    return true;
    145             for (int j=L[i]; j!=i; j=L[j]) {
    146                 restore(col[j]);
    147             }
    148         }
    149         restore(c);
    150         
    151         return false;
    152     }
    153     
    154     void solve(vi& v) {
    155         
    156         dfs(0);
    157         
    158         if (cnt == 1) {
    159             v.clr();
    160             rep(i, 0, ansd)
    161                 v.pb(ans_[i]);
    162         }
    163     }
    164     
    165 } DLX;
    166 
    167 DLX solver;
    168 int n, n2, n2n2;
    169 const int maxl = 20;
    170 char M[maxl][maxl], M_[maxl][maxl];
    171 const int SLOT     = 0;
    172 const int ROW      = 1;
    173 const int COL    = 2;
    174 const int SUB    = 3;
    175 
    176 int encode(int a, int b, int c) {
    177     return a*n2n2 + b*n2 + c + 1;
    178 }
    179 
    180 void decode(int code, int& a, int& b, int& c) {
    181     --code;
    182     c = code % n2;
    183     code /= n2;
    184     b = code % n2;
    185     code /= n2;
    186     a = code;
    187 }
    188 
    189 int getVal(char c) {
    190     if (c>='0' && c<='9')    return c-'1';
    191     return c-'A'+9;
    192 }
    193 
    194 int getChar(int val) {
    195     if (val < 9)    return val+'1';
    196     return val-9+'A';
    197 }
    198 
    199 void init() {
    200     n2 = n * n;
    201     n2n2 = n2 * n2;
    202 }
    203 
    204 void solve(vi& ans) {
    205     solver.init(4 * n2n2);
    206         
    207     rep(r, 0, n2) {
    208         rep(c, 0, n2) {
    209             rep(v, 0, n2) {
    210                 if (M[r][c]=='.' || v==getVal(M[r][c])) {
    211                     vi columns;
    212                     columns.pb(encode(SLOT, r, c));
    213                     columns.pb(encode(ROW, r, v));
    214                     columns.pb(encode(COL, c, v));
    215                     columns.pb(encode(SUB, r/n*n+c/n, v));
    216                     solver.addRow(encode(r, c, v), columns);
    217                 }
    218             }
    219         }
    220     }
    221     
    222     solver.solve(ans);
    223 }
    224 
    225 int main() {
    226     ios::sync_with_stdio(false);
    227     #ifndef ONLINE_JUDGE
    228         freopen("data.in", "r", stdin);
    229         freopen("data.out", "w", stdout);
    230     #endif
    231     
    232     vi ans, tmp;
    233     
    234     while (scanf("%d", &n) != EOF) {
    235         init();
    236         rep(i, 0, n2)
    237             scanf("%s", M[i]);        
    238         
    239         solve(ans);
    240         
    241         if (solver.cnt == 0) {
    242             puts("No Solution");
    243             continue;
    244         } else if (solver.cnt > 1) {
    245             puts("Multiple Solutions");
    246             continue;
    247         }
    248         
    249         // check if is minimal
    250         bool flag = true;
    251         
    252         rep(r, 0, n2) {
    253             rep(c, 0, n2) {
    254                 if (M[r][c] != '.') {
    255                     char ch = M[r][c];
    256                     M[r][c] = '.';
    257                     solve(tmp);
    258                     M[r][c] = ch;
    259                     if (solver.cnt <= 1) {
    260                         flag = false;
    261                         goto _output;
    262                     }
    263                 }
    264             }
    265         }
    266         
    267         _output:
    268         if (flag) {        
    269             int sz = SZ(ans);
    270             rep(i, 0, sz) {
    271                 int r, c, v;
    272                 decode(ans[i], r, c, v);
    273                 char ch = getChar(v);
    274                 M[r][c] = ch;
    275             }
    276             
    277             rep(i, 0, n2)
    278                 puts(M[i]);
    279         } else {
    280             puts("Not Minimal");
    281         }
    282     }
    283     
    284     #ifndef ONLINE_JUDGE
    285         printf("time = %d.
    ", (int)clock());
    286     #endif
    287     
    288     return 0;
    289 }
  • 相关阅读:
    二叉链表(双叉链表)实现二叉树
    队列知识
    windows下Anaconda3配置TensorFlow深度学习库
    栈的顺序结构和链式结构实现
    Anaconda中配置Pyspark的Spark开发环境
    Scala学习笔记(3)-表达式归纳
    SparkR-Install
    推荐系统之最小二乘法ALS的Spark实现
    linux查看主机端口进程命令
    使用redis的五个注意事项
  • 原文地址:https://www.cnblogs.com/bombe1013/p/4975863.html
Copyright © 2020-2023  润新知