【HDU】3111 Sudoku

  1 #include<cstdio>

  2 #include<cstring>

  3 #define MAXM 10

  4 #define MAXL 324

  5 #define MAXN 240000

  6 #define INF 0x7FFFFFFF

  7 char sd[MAXM][MAXM];

  8 int L[MAXN], R[MAXN], U[MAXN], D[MAXN], H[MAXN];

  9 int size, C[MAXN], S[MAXN], X[MAXN], Q[MAXN], vis[MAXL * 3];

 10 void Read()

 11 {

 12     int i, j;

 13     for (i = 1; i < MAXM; i++)

 14     {

 15         for (j = 1; j < MAXM; j++)

 16             scanf(" %c", &sd[i][j]);

 17     }

 18 }

 19 void Init()

 20 {

 21     int i;

 22     for (i = 0; i <= MAXL; i++)

 23     {

 24         L[i + 1] = i;

 25         R[i] = i + 1;

 26         U[i] = D[i] = i;

 27         S[i] = 0;

 28     }

 29     R[MAXL] = 0;

 30     size = MAXL + 1;

 31 }

 32 void Remove(int c)

 33 {

 34     int i, j;

 35     L[R[c]] = L[c];

 36     R[L[c]] = R[c];

 37     for (i = D[c]; i != c; i = D[i])

 38     {

 39         for (j = R[i]; j != i; j = R[j])

 40         {

 41             U[D[j]] = U[j];

 42             D[U[j]] = D[j];

 43             S[C[j]]--;

 44         }

 45     }

 46 }

 47 void Resume(int c)

 48 {

 49     int i, j;

 50     L[R[c]] = c;

 51     R[L[c]] = c;

 52     for (i = D[c]; i != c; i = D[i])

 53     {

 54         for (j = R[i]; j != i; j = R[j])

 55         {

 56             U[D[j]] = j;

 57             D[U[j]] = j;

 58             S[C[j]]++;

 59         }

 60     }

 61 }

 62 inline void Link(int r, int c)

 63 {

 64     D[size] = D[c];

 65     U[size] = c;

 66     U[D[c]] = size;

 67     D[c] = size;

 68     if (H[r] < 0)

 69         H[r] = L[size] = R[size] = size;

 70     else

 71     {

 72         L[size] = H[r];

 73         R[size] = R[H[r]];

 74         L[R[H[r]]] = size;

 75         R[H[r]] = size;

 76     }

 77     S[c]++;

 78     X[size] = r;

 79     C[size++] = c;

 80 }

 81 bool Dance(int now)

 82 {

 83     int i, j, c, temp;

 84     if (R[0] == 0)

 85         return true;

 86     for (temp = INF,i = R[0]; i; i = R[i])

 87     {

 88         if (S[i] < temp)

 89         {

 90             temp = S[i];

 91             c = i;

 92         }

 93     }

 94     Remove(c);

 95     for (i = D[c]; i != c; i = D[i])

 96     {

 97         vis[X[i]] = true;

 98         for (j = R[i]; j != i; j = R[j])

 99             Remove(C[j]);

100         if (Dance(now + 1))

101             return true;

102         for (j = L[i]; j != i; j = L[j])

103             Resume(C[j]);

104         vis[X[i]] = false;

105     }

106     Resume(c);

107     return false;

108 }

109 int main()

110 {

111     int i, j, k, r, ca;

112     char s[10];

113     scanf("%d", &ca);

114     while (ca--)

115     {

116         Read();

117         Init();

118         for (r = 0, i = 1; i < MAXM; i++)

119         {

120             for (j = 1; j < MAXM; j++)

121             {

122                 if (sd[i][j] == '?')

123                 {

124                     for (k = 1; k < MAXM; k++)

125                     {

126                         H[++r] = -1;

127                         Q[r] = k;

128                         Link(r, (i - 1) * 9 + k);

129                         Link(r, 81 + (j - 1) * 9 + k);

130                         Link(r, 162 + ((i - 1) / 3 * 3 + (j - 1) / 3) * 9 + k);

131                         Link(r, 243 + (i - 1) * 9 + j);

132                     }

133                 }

134                 else

135                 {

136                     H[++r] = -1;

137                     k = sd[i][j] - '0';

138                     Q[r] = k;

139                     Link(r, (i - 1) * 9 + k);

140                     Link(r, 81 + (j - 1) * 9 + k);

141                     Link(r, 162 + ((i - 1) / 3 * 3 + (j - 1) / 3) * 9 + k);

142                     Link(r, 243 + (i - 1) * 9 + j);

143                 }

144             }

145         }

146         memset(vis, false, sizeof(vis));

147         if (Dance(0))

148         {

149             for (k = 0, i = 1; i <= r; i++)

150             {

151                 if (vis[i])

152                 {

153                     k++;

154                     printf("%d", Q[i]);

155                     if (k % 9 == 0)

156                         putchar('\n');

157                 }

158             }

159         }

160         else

161             puts("impossible");

162         if (ca)

163         {

164             scanf(" %s", s);

165             puts(s);

166         }

167     }

168     return 0;

169 }

你可能感兴趣的:(sudo)