zoukankan      html  css  js  c++  java
  • 【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 }
  • 相关阅读:
    【SCOI 2011】 糖果
    【POJ 3159】 Candies
    【POJ 1716】 Integer Intervals
    【POJ 2983】 Is the information reliable?
    【POJ 1364】 King
    【POJ 1201】 Intervals
    【POJ 1804】 Brainman
    6月10日省中提高组题解
    【POJ 3352】 Road Construction
    【POJ 1144】 Network
  • 原文地址:https://www.cnblogs.com/bombe1013/p/4975863.html
Copyright © 2011-2022 走看看