zoukankan      html  css  js  c++  java
  • 【FOJ】2076 SUDOKU

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<set>
      4 #define MAXN 9
      5 #define MAXM 500000
      6 #define INF 0x7FFFFFFF
      7 using namespace std;
      8 char sd[MAXN][MAXN];
      9 int L[MAXM], R[MAXM], U[MAXM], D[MAXM];
     10 int H[MAXM], S[MAXM], C[MAXM], pos[MAXN << 3][MAXN << 3];
     11 int size, cnt;
     12 void Init(int m)
     13 {
     14     int i;
     15     for (i = 0; i <= m; i++)
     16     {
     17         R[i] = i + 1;
     18         L[i + 1] = i;
     19         U[i] = D[i] = i;
     20         S[i] = 0;
     21     }
     22     R[m] = 0;
     23     size = m + 1;
     24 }
     25 void Remove(int c)
     26 {
     27     int i, j;
     28     L[R[c]] = L[c];
     29     R[L[c]] = R[c];
     30     for (i = D[c]; i != c; i = D[i])
     31     {
     32         for (j = R[i]; j != i; j = R[j])
     33         {
     34             U[D[j]] = U[j];
     35             D[U[j]] = D[j];
     36             S[C[j]]--;
     37         }
     38     }
     39 }
     40 void Resume(int c)
     41 {
     42     int i, j;
     43     L[R[c]] = R[L[c]] = c;
     44     for (i = D[c]; i != c; i = D[i])
     45     {
     46         for (j = R[i]; j != i; j = R[j])
     47         {
     48             U[D[j]] = D[U[j]] = j;
     49             S[C[j]]++;
     50         }
     51     }
     52 }
     53 inline void Link(int r, int c)
     54 {
     55     U[size] = c;
     56     D[size] = D[c];
     57     U[D[c]] = size;
     58     D[c] = size;
     59     if (H[r] < 0)
     60         H[r] = L[size] = R[size] = size;
     61     else
     62     {
     63         L[size] = H[r];
     64         R[size] = R[H[r]];
     65         L[R[H[r]]] = size;
     66         R[H[r]] = size;
     67     }
     68     S[c]++;
     69     C[size++] = c;
     70 }
     71 void Dance()
     72 {
     73     if (R[0] == 0)
     74         cnt++;
     75     else
     76     {
     77         int i, j, temp, c;
     78         for (temp = INF,i = R[0]; i; i = R[i])
     79         {
     80             if (temp > S[i])
     81             {
     82                 temp = S[i];
     83                 c = i;
     84             }
     85         }
     86         Remove(c);
     87         for (i = D[c]; i != c; i = D[i])
     88         {
     89             for (j = R[i]; j != i; j = R[j])
     90                 Remove(C[j]);
     91             Dance();
     92             for (j = L[i]; j != i; j = L[j])
     93                 Resume(C[j]);
     94         }
     95         Resume(c);
     96     }
     97 }
     98 void Build()
     99 {
    100     set<int> myset;
    101     int i, j, k, r, t;
    102     for (i = r = 0; i < MAXN; i++)
    103     {
    104         for (j = 0; j < MAXN; j++)
    105         {
    106             if (sd[i][j] == '0')
    107             {
    108                 for (k = 1; k <= MAXN; k++)
    109                 {
    110                     H[++r] = -1;
    111                     Link(r, i * 9 + k);
    112                     Link(r, 81 + j * 9 + k);
    113                     Link(r, 162 + (i / 3 * 3 + j / 3) * 9 + k);
    114                     Link(r, 243 + i * 9 + j + 1);
    115                 }
    116             }
    117             else if (sd[i][j] >= '1' && sd[i][j] <= '9')
    118             {
    119                 k = sd[i][j] - '0';
    120                 H[++r] = -1;
    121                 Link(r, i * 9 + k);
    122                 Link(r, 81 + j * 9 + k);
    123                 Link(r, 162 + (i / 3 * 3 + j / 3) * 9 + k);
    124                 Link(r, 243 + i * 9 + j + 1);
    125             }
    126         }
    127     }
    128     for (i = 0; i < 26; i++)
    129     {
    130         for (j = 0; j < MAXN; j++)
    131         {
    132             pos[i][j] = ++r;
    133             H[r] = -1;
    134         }
    135     }
    136     for (i = 0; i < MAXN; i++)
    137     {
    138         for (j = 0; j < MAXN; j++)
    139         {
    140             if (sd[i][j] >= 'a' && sd[i][j] <= 'z')
    141             {
    142                 t = sd[i][j] - 'a';
    143                 for (k = 1; k <= MAXN; k++)
    144                 {
    145                     Link(pos[t][k - 1], i * 9 + k);
    146                     Link(pos[t][k - 1], 81 + j * 9 + k);
    147                     Link(pos[t][k - 1], 162 + (i / 3 * 3 + j / 3) * 9 + k);
    148                     Link(pos[t][k - 1], 243 + i * 9 + j + 1);
    149                     if (!myset.count(t * 26 + k - 1))
    150                     {
    151                         Link(pos[t][k - 1], 324 + k);
    152                         myset.insert(t * 26 + k - 1);
    153                     }
    154                 }
    155             }
    156         }
    157     }
    158     for (i = 1; i <= MAXN; i++)
    159     {
    160         H[++r] = -1;
    161         Link(r, 324 + i);
    162     }
    163 }
    164 inline int Get(char ch)
    165 {
    166     if (ch >= '0' && ch <= '9')
    167         return ch - '0';
    168     return ch - 'a' + 10;
    169 }
    170 bool OK()
    171 {
    172     int i, j, k;
    173     bool x[MAXN << 3], letter[MAXN << 3], y[MAXN][MAXN << 3];
    174     memset(letter, false, sizeof(letter));
    175     memset(y, false, sizeof(y));
    176     for (i = 0; i < MAXN; i++)
    177     {
    178         memset(x, false, sizeof(x));
    179         for (j = 0; j < MAXN; j++)
    180         {
    181             k = Get(sd[i][j]);
    182             if (k && y[i / 3 * 3 + j / 3][k])
    183                 return false;
    184             y[i / 3 * 3 + j / 3][k] = true;
    185             if (k > 9)
    186                 letter[k] = true;
    187             if (k && x[k])
    188                 return false;
    189             x[k] = true;
    190         }
    191     }
    192     for (i = k = 0; i < MAXN << 3; i++)
    193     {
    194         if (letter[i])
    195             k++;
    196     }
    197     if (k > 9)
    198         return false;
    199     for (j = 0; j < MAXN; j++)
    200     {
    201         memset(x, false, sizeof(x));
    202         for (i = 0; i < MAXN; i++)
    203         {
    204             k = Get(sd[i][j]);
    205             if (k && x[k])
    206                 return false;
    207             x[k] = true;
    208         }
    209     }
    210     return true;
    211 }
    212 int main()
    213 {
    214     int c, i, j;
    215     scanf("%d", &c);
    216     while (c--)
    217     {
    218         Init(333);
    219         for (i = cnt = 0; i < MAXN; i++)
    220         {
    221             for (j = 0; j < MAXN; j++)
    222                 scanf(" %c", &sd[i][j]);
    223         }
    224         if (OK())
    225         {
    226             Build();
    227             Dance();
    228         }
    229         printf("%d\n", cnt);
    230     }
    231     return 0;
    232 }
  • 相关阅读:
    剑指offer---第一个只出现一次的字符
    剑指offer---两个链表的第一个公共结点
    剑指offer---丑数
    剑指offer---旋转数组的最小数字
    剑指offer---滑动窗口的最大值
    剑指offer---重建二叉树
    剑指offer---数据流中的中位数
    剑指offer---二叉搜索树的第K个节点
    剑指offer--对称二叉树
    剑指offer---把二叉树打印成多行
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2609245.html
Copyright © 2011-2022 走看看