【SPOJ】1771 Yet Another N-Queen Problem

  1 #include<cstdio>

  2 #include<cstring>

  3 #define MAXN 1000000

  4 #define MAXM 3000

  5 #define INF 0x7FFFFFFF

  6 int L[MAXN], R[MAXN], U[MAXN], D[MAXN];

  7 int H[MAXM], S[MAXM], C[MAXN], X[MAXN], Y[MAXN], Q[MAXM], ans[MAXM], pos[MAXM];

  8 int n, size;

  9 bool vis[MAXM];

 10 void Init(int m) {

 11     int i;

 12     for (i = 0; i <= m; i++) {

 13         R[i] = i + 1;

 14         L[i + 1] = i;

 15         U[i] = D[i] = i;

 16         S[i] = 0;

 17     }

 18     R[m] = 0;

 19     size = m + 1;

 20 }

 21 inline void Link(int r, int c, int row) {

 22     D[size] = D[c];

 23     U[size] = c;

 24     U[D[c]] = size;

 25     D[c] = size;

 26     if (H[r] < 0)

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

 28     else {

 29         L[size] = H[r];

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

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

 32         R[H[r]] = size;

 33     }

 34     S[c]++;

 35     X[size] = r;

 36     Y[size] = row;

 37     C[size++] = c;

 38 }

 39 void Remove(int c) {

 40     int i, j;

 41     L[R[c]] = L[c];

 42     R[L[c]] = R[c];

 43     for (i = D[c]; i != c; i = D[i]) {

 44         for (j = R[i]; j != i; j = R[j]) {

 45             U[D[j]] = U[j];

 46             D[U[j]] = D[j];

 47             S[C[j]]--;

 48         }

 49     }

 50 }

 51 void Resume(int c) {

 52     int i, j;

 53     R[L[c]] = L[R[c]] = c;

 54     for (i = D[c]; i != c; i = D[i]) {

 55         for (j = R[i]; j != i; j = R[j]) {

 56             U[D[j]] = D[U[j]] = j;

 57             S[C[j]]++;

 58         }

 59     }

 60 }

 61 bool Dance(int now) {

 62     int i, j, temp, c;

 63     if (now >= n) {

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

 65             ans[Y[pos[i]]] = Q[X[pos[i]]];

 66         printf("%d", ans[1]);

 67         for (i = 2; i <= n; i++)

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

 69         putchar('\n');

 70         return true;

 71     }

 72     if (R[0] == 0)

 73         return false;

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

 75         if (i > n)

 76             break;

 77         if (temp > S[i]) {

 78             temp = S[i];

 79             c = i;

 80         }

 81     }

 82     Remove(c);

 83     for (i = D[c]; i != c; i = D[i]) {

 84         pos[now] = i;

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

 86             Remove(C[j]);

 87         if (Dance(now + 1))

 88             return true;

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

 90             Resume(C[j]);

 91         vis[X[i]] = false;

 92     }

 93     Resume(c);

 94     return false;

 95 }

 96 void Build(int r, int c, int &k, bool flag) {

 97     int p1, p2, p3, p4;

 98     p1 = r;

 99     p2 = n + c;

100     p3 = n + n + r + c - 1;

101     p4 = 4 * n - 1 + r - c + n;

102     if (flag)

103         vis[p1] = vis[p2] = vis[p3] = vis[p4] = true;

104     if (flag || (!vis[p1] && !vis[p2] && !vis[p3] && !vis[p4])) {

105         H[++k] = -1;

106         Link(k, p1, r);

107         Link(k, p2, r);

108         Link(k, p3, r);

109         Link(k, p4, r);

110         Q[k] = c;

111     }

112 }

113 int main() {

114     int i, j, k;

115     while (~scanf("%d", &n)) {

116         Init(6 * n - 2);

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

118         for (k = 0, i = 1; i <= n; i++) {

119             scanf("%d", &j);

120             if (j)

121                 Build(i, j, k, true);

122         }

123         for (i = 1; i <= n; i++) {

124             for (j = 1; j <= n; j++)

125                 Build(i, j, k, false);

126         }

127         Dance(0);

128     }

129     return 0;

130 }

你可能感兴趣的:(poj)