SPOJ_1771

    通过这个题目进一步训练了Dancing Links解决N皇后问题的技巧。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define INF 1000000000
const int MAXN = 50;
const int MAXmn = MAXN * MAXN * 4 + MAXN * 6 + MAXN;
const int MAXnn = MAXN * 6 + MAXN;
int N, size;
int U[MAXmn], D[MAXmn], L[MAXmn], R[MAXmn], H[MAXmn], C[MAXmn], X[MAXmn];
int Q[MAXnn], S[MAXnn], x[MAXnn], y[MAXnn], r[MAXnn], visc[MAXnn];
int cmp(const void *_p, const void *_q)
{
int *p = (int *)_p;
int *q = (int *)_q;
return x[*p] - x[*q];
}
void prepare(int r, int c)
{
int i, j;
for(i = 0; i <= c; i ++)
{
S[i] = 0;
U[i] = D[i] = i;
R[i] = i + 1;
L[i + 1] = i;
}
R[c] = 0;
size = c;
while(r)
H[r --] = -1;
}
void place(int &r, int &c1, int &c2, int &c3, int &c4, int i, int j)
{
r = (i - 1) * N + j;
c1 = j;
c2 = N + i;
c3 = N * 3 + i - j;
c4 = N * 4 + i + j - 2;
}
void link(int r,int c)
{
size ++;
C[size] = c;
S[c] ++;
X[size] = r;
D[size] = D[c];
U[D[c]] = size;
U[size] = c;
D[c] = size;
if(H[r] < 0)
H[r] = L[size] = R[size] = size;
else
{
R[size] = R[H[r]];
L[R[H[r]]] = size;
L[size] = H[r];
R[H[r]] = size;
}
}
int init()
{
int i, j, r, c1, c2, c3, c4;
if(scanf("%d", &N) != 1)
return 0;
prepare(N * N, N * 6 - 2);
memset(visc, 0, sizeof(visc));
for(i = 1; i <= N; i ++)
{
scanf("%d", &j);
if(j)
{
place(r, c1, c2, c3, c4, i, j);
link(r, c1), link(r, c2), link(r, c3), link(r, c4);
visc[c1] = visc[c2] = visc[c3] = visc[c4] = 1;
}
}
for(i = 1; i <= N; i ++)
for(j = 1; j <= N; j ++)
{
place(r, c1, c2, c3, c4, i, j);
if(visc[c1] || visc[c2] || visc[c3] || visc[c4])
continue;
link(r, c1), link(r, c2), link(r, c3), link(r, c4);
}
return 1;
}
void remove(int c)
{
int i, j;
L[R[c]] = L[c];
R[L[c]] = R[c];
for(i = D[c]; i != c; i = D[i])
for(j = R[i]; j != i; j = R[j])
{
U[D[j]] = U[j];
D[U[j]] = D[j];
S[C[j]] --;
}
}
void resume(int c)
{
int i, j;
for(i = U[c]; i != c; i = U[i])
for(j = L[i]; j != i; j = L[j])
{
S[C[j]] ++;
U[D[j]] = j;
D[U[j]] = j;
}
L[R[c]] = c;
R[L[c]] = c;
}
int dance(int cur)
{
int i, j, c, temp;
if(cur >= N)
{
for(i = 0; i < cur; i ++)
{
x[i] = (X[Q[i]] - 1) / N + 1;
y[i] = (X[Q[i]] - 1) % N + 1;
}
return 1;
}
if(!R[0])
return 0;
temp = INF;
for(i = R[0]; i <= N; i = R[i])
if(S[i] < temp)
{
temp = S[i];
c = i;
}
remove(c);
for(i = D[c]; i != c; i = D[i])
{
Q[cur] = i;
for(j = R[i]; j != i; j = R[j])
{
remove(C[j]);
}
if(dance(cur + 1))
return 1;
for(j = L[i]; j != i; j = L[j])
resume(C[j]);
}
resume(c);
return 0;
}
void printresult()
{
int i;
for(i = 0; i < N; i ++)
r[i] = i;
qsort(r, N, sizeof(r[0]), cmp);
for(i = 0; i < N; i ++)
{
if(i)
printf(" ");
printf("%d", y[r[i]]);
}
printf("\n");
}
int main()
{
while(init())
{
if(dance(0))
printresult();
}
return 0;
}


posted on 2011-10-12 01:15  Staginner  阅读(390)  评论(0编辑  收藏  举报