【HDU】4069 Squiggly Sudoku

  1 #include<cstdio>

  2 #include<cstring>

  3 #define MAXN 9

  4 #define MAXH 800

  5 #define MAXL 324

  6 #define MAXM 240000

  7 #define INF 0x7FFFFFFF

  8 int size, cnt, a[MAXN][MAXN], sd[MAXN][MAXN], belong[MAXN][MAXN];

  9 int L[MAXM], R[MAXM], U[MAXM], D[MAXM], C[MAXM], X[MAXM];

 10 int S[MAXH], H[MAXH], Q[MAXH], ans[MAXL];

 11 bool vis[MAXH];

 12 void Dir(int x, int y, bool &up, bool &right, bool &down, bool &left)

 13 {

 14     sd[x][y] = a[x][y];

 15     up = right = down = left = false;

 16     if (sd[x][y] >= 128)

 17     {

 18         sd[x][y] -= 128;

 19         left = true;

 20     }

 21     if (sd[x][y] >= 64)

 22     {

 23         sd[x][y] -= 64;

 24         down = true;

 25     }

 26     if (sd[x][y] >= 32)

 27     {

 28         sd[x][y] -= 32;

 29         right = true;

 30     }

 31     if (sd[x][y] >= 16)

 32     {

 33         sd[x][y] -= 16;

 34         up = true;

 35     }

 36 

 37 }

 38 void DFS(int x, int y, int color)

 39 {

 40     bool up, right, down, left;

 41     belong[x][y] = color;

 42     Dir(x, y, up, right, down, left);

 43     if (!up && !belong[x - 1][y])

 44         DFS(x - 1, y, color);

 45     if (!down && !belong[x + 1][y])

 46         DFS(x + 1, y, color);

 47     if (!right && !belong[x][y + 1])

 48         DFS(x, y + 1, color);

 49     if (!left && !belong[x][y - 1])

 50         DFS(x, y - 1, color);

 51 }

 52 void Init()

 53 {

 54     int i;

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

 56     {

 57         L[i + 1] = i;

 58         R[i] = i + 1;

 59         U[i] = D[i] = i;

 60         S[i] = 0;

 61     }

 62     R[MAXL] = 0;

 63     size = MAXL + 1;

 64 }

 65 void Remove(int c)

 66 {

 67     int i, j;

 68     L[R[c]] = L[c];

 69     R[L[c]] = R[c];

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

 71     {

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

 73         {

 74             U[D[j]] = U[j];

 75             D[U[j]] = D[j];

 76             S[C[j]]--;

 77         }

 78     }

 79 }

 80 void Resume(int c)

 81 {

 82     int i, j;

 83     L[R[c]] = c;

 84     R[L[c]] = c;

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

 86     {

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

 88         {

 89             U[D[j]] = j;

 90             D[U[j]] = j;

 91             S[C[j]]++;

 92         }

 93     }

 94 }

 95 inline void Link(int r, int c)

 96 {

 97     D[size] = D[c];

 98     U[size] = c;

 99     U[D[c]] = size;

100     D[c] = size;

101     if (H[r] < 0)

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

103     else

104     {

105         L[size] = H[r];

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

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

108         R[H[r]] = size;

109     }

110     S[c]++;

111     X[size] = r;

112     C[size++] = c;

113 }

114 bool Dance(int r)

115 {

116     int i, j, temp, c;

117     if (R[0] == 0)

118     {

119         if (!cnt)

120         {

121             for (i = j = 1; i <= r; i++)

122             {

123                 if (vis[i])

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

125             }

126         }

127         cnt++;

128         return cnt > 1;

129     }

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

131     {

132         if (temp > S[i])

133         {

134             temp = S[i];

135             c = i;

136         }

137     }

138     Remove(c);

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

140     {

141         vis[X[i]] = true;

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

143             Remove(C[j]);

144         if (Dance(r))

145             return true;

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

147             Resume(C[j]);

148         vis[X[i]] = false;

149     }

150     Resume(c);

151     return false;

152 }

153 int main()

154 {

155     int c, i, j, k, r, ca = 1;

156     scanf("%d", &c);

157     while (c--)

158     {

159         memset(belong, 0, sizeof(belong));

160         for (i = 0; i < MAXN; i++)

161         {

162             for (j = 0; j < MAXN; j++)

163                 scanf("%d", &a[i][j]);

164         }

165         for (i = k = 0; i < MAXN; i++)

166         {

167             for (j = 0; j < MAXN; j++)

168             {

169                 if (!belong[i][j])

170                     DFS(i, j, ++k);

171             }

172         }

173         Init();

174         for (i = r = 0; i < MAXN; i++)

175         {

176             for (j = 0; j < MAXN; j++)

177             {

178                 if (sd[i][j])

179                 {

180                     k = sd[i][j];

181                     H[++r] = -1;

182                     Q[r] = k;

183                     Link(r, i * 9 + k);

184                     Link(r, 81 + j * 9 + k);

185                     Link(r, 162 + (belong[i][j] - 1) * 9 + k);

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

187                 }

188                 else

189                 {

190                     for (k = 1; k <= MAXN; k++)

191                     {

192                         H[++r] = -1;

193                         Q[r] = k;

194                         Link(r, i * 9 + k);

195                         Link(r, 81 + j * 9 + k);

196                         Link(r, 162 + (belong[i][j] - 1) * 9 + k);

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

198                     }

199                 }

200             }

201         }

202         cnt = 0;

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

204         Dance(r);

205         printf("Case %d:\n", ca++);

206         if (cnt == 0)

207             puts("No solution");

208         else if (cnt > 1)

209             puts("Multiple Solutions");

210         else

211         {

212             for (i = 1; i <= 81; i++)

213             {

214                 printf("%d", ans[i]);

215                 if (i % 9 == 0)

216                     putchar('\n');

217             }

218         }

219     }

220     return 0;

221 }

你可能感兴趣的:(sudo)