【HDU】3909 Sudoku

  1 #include<cstdio>

  2 #include<cstring>

  3 #define SD 16

  4 #define MAXN 2400000

  5 #define MAXM 4100

  6 #define INF 0x7FFFFFFF

  7 char sd[SD][SD];

  8 int L[MAXN], R[MAXN], U[MAXN], D[MAXN], C[MAXN], X[MAXN];

  9 int size, cnt, row, S[MAXM], H[MAXM], Q[MAXM], ans[MAXM];

 10 bool vis[MAXM];

 11 void Init(int m)

 12 {

 13     int i;

 14     for (i = 0; i <= m; i++)

 15     {

 16         R[i] = i + 1;

 17         L[i + 1] = i;

 18         U[i] = D[i] = i;

 19         S[i] = 0;

 20     }

 21     R[m] = 0;

 22     size = m + 1;

 23 }

 24 void Remove(int c)

 25 {

 26     int i, j;

 27     L[R[c]] = L[c];

 28     R[L[c]] = R[c];

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

 30     {

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

 32         {

 33             U[D[j]] = U[j];

 34             D[U[j]] = D[j];

 35             S[C[j]]--;

 36         }

 37     }

 38 }

 39 void Resume(int c)

 40 {

 41     int i, j;

 42     L[R[c]] = c;

 43     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]] = j;

 49             D[U[j]] = j;

 50             S[C[j]]++;

 51         }

 52     }

 53 }

 54 inline void Link(int r, int c)

 55 {

 56     D[size] = D[c];

 57     U[size] = c;

 58     U[D[c]] = size;

 59     D[c] = size;

 60     if (H[r] < 0)

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

 62     else

 63     {

 64         L[size] = H[r];

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

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

 67         R[H[r]] = size;

 68     }

 69     S[c]++;

 70     X[size] = r;

 71     C[size++] = c;

 72 }

 73 void Build(int n)

 74 {

 75     int i, j, k, t;

 76     Init(n * n << 2);

 77     if (n == 4)

 78         t = 2;

 79     else if (n == 9)

 80         t = 3;

 81     else

 82         t = 4;

 83     for (i = row = 0; i < n; i++)

 84     {

 85         for (j = 0; j < n; j++)

 86         {

 87             if (sd[i][j] == '.')

 88             {

 89                 for (k = 0; k < n; k++)

 90                 {

 91                     H[++row] = -1;

 92                     Q[row] = k;

 93                     Link(row, i * n + k + 1);

 94                     Link(row, n * n + j * n + k + 1);

 95                     Link(row, (n * n << 1) + (i / t * t + j / t) * n + k + 1);

 96                     Link(row, n * n * 3 + i * n + j + 1);

 97                 }

 98             }

 99             else

100             {

101                 if (sd[i][j] >= '0' && sd[i][j] <= '9')

102                     k = sd[i][j] - '1';

103                 else

104                     k = sd[i][j] - 'A' + 9;

105                 H[++row] = -1;

106                 Q[row] = k;

107                 Link(row, i * n + k + 1);

108                 Link(row, n * n + j * n + k + 1);

109                 Link(row, (n * n << 1) + (i / t * t + j / t) * n + k + 1);

110                 Link(row, n * n * 3 + i * n + j + 1);

111             }

112         }

113     }

114 }

115 bool Dance(bool flag)

116 {

117     int i, j, temp, c;

118     if (R[0] == 0)

119     {

120         if (flag && !cnt)

121         {

122             for (i = j = 1; i <= row; i++)

123             {

124                 if (vis[i])

125                     ans[j++] = Q[i];

126             }

127         }

128         cnt++;

129         return cnt > 1;

130     }

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

132     {

133         if (temp > S[i])

134         {

135             temp = S[i];

136             c = i;

137         }

138     }

139     Remove(c);

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

141     {

142         vis[X[i]] = true;

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

144             Remove(C[j]);

145         if (Dance(flag))

146             return true;

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

148             Resume(C[j]);

149         vis[X[i]] = false;

150     }

151     Resume(c);

152     return false;

153 }

154 bool OK(int n)

155 {

156     int i, j;

157     char temp;

158     for (i = 0; i < n; i++)

159     {

160         for (j = 0; j < n; j++)

161         {

162             if (sd[i][j] != '.')

163             {

164                 temp = sd[i][j];

165                 sd[i][j] = '.';

166                 Build(n);

167                 cnt = 0;

168                 Dance(false);

169                 if (cnt < 2)

170                     return false;

171                 sd[i][j] = temp;

172             }

173         }

174     }

175     return true;

176 }

177 int main()

178 {

179     int n, i, j;

180     while (~scanf("%d", &n))

181     {

182         n *= n;

183         for (cnt = i = 0; i < n; i++)

184         {

185             for (j = 0; j < n; j++)

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

187         }

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

189         Build(n);

190         Dance(true);

191         if (cnt == 0)

192             puts("No Solution");

193         else if (cnt > 1)

194             puts("Multiple Solutions");

195         else

196         {

197             if (OK(n))

198             {

199                 for (i = 1; i <= n * n; i++)

200                 {

201                     if (ans[i] < 9)

202                         putchar(ans[i] + 1 + '0');

203                     else

204                         putchar(ans[i] - 9 + 'A');

205                     if (i % n == 0)

206                         putchar('\n');

207                 }

208             }

209             else

210                 puts("Not Minimal");

211         }

212     }

213     return 0;

214 }

你可能感兴趣的:(sudo)