NOI2005 智慧珠游戏

【原题见 这里】
很明显的精确覆盖的模型,12个零件,再加上它们经过旋转、翻转后的不同形状,共60种,每种又可以放在不同的位置(只看最左上的那个珠子)一种零件的一种位置就是一行。列(限制)有两种:每个格子只能放一个(55列),以及每个零件(注意是每个零件,不是每种零件)只能用一次(12列),共67列。预先放的那些零件可以看成预先选中的行。然后DLX精确覆盖即可。

下面是DLX精确覆盖的几个易疵点:
(1)整个矩阵的行数和列数不能疵(比如本题是1644行,67列);
(2)注意init_d()、add_node(int, int)、delcol(int)、resucol(int)中的一些细节:
【1】init_d()中,是否把m写成了n;
【2】add_node(int, int)中,是否写了cols[c]++;
【3】delcol(int)和resucol(int)中,变量有木有疵(比如把i写成j之类的),另外是否对cols进行了处理;
(3)如果有一些行预先被选中,注意在删掉这些行的时候是否删光,不要漏了行头(rowh);
(4)注意区分行号、列号和结点下标,delcol(int x)和resucol(int x)中的参数x一定是列号,而记录可行解的res数组里存放的一定是行号;
(5)结点的行、列号均从1开始(第0行、第0列有特殊意义);
(6)如果有多组数据,检查在每组数据之前是否将所有数组初始化;

本题代码:
#include  < iostream >
#include 
< stdio.h >
using   namespace  std;
#define  re(i, n) for (int i=0; i<n; i++)
#define  re1(i, n) for (int i=1; i<=n; i++)
#define  re3(i, l, r) for (int i=l; i<=r; i++)
#define  set(i, j, x, y) PX[i][j] = x; PY[i][j] = y;
const   int  S  =   10 , n  =   1644 , m  =   67 , T  =   60 , INF  =   ~ 0U   >>   2 ;;
const   int  LL[ 12 =  { 0 4 6 14 15 19 27 31 39 47 48 52 }, RR[ 12 =  { 3 5 13 14 18 26 30 38 46 47 51 59 };
const   char  SSS[T  +   1 =   " AAAABBCCCCCCCCDEEEEFFFFFFFFGGGGHHHHHHHHIIIIIIIIJKKKKLLLLLLLL " ;
struct  dlnode {
    
int  r, c, U, D, L, R;
} d[(n 
+   1 *  (m  +   1 )];
int  rowh[n  +   1 ], cols[m  +   1 ], nodes, PX[T][ 5 ], PY[T][ 5 ], len[T], No[S][S], pos[n  +   1 ][ 3 ], _pos[T][S][S], res[n], res_len;
char  a[S][S];
bool  vst[ 12 ];
void  init_d()
{
    re3(i, 
0 , m) {d[i].U  =  d[i].D  =  i; d[i].L  =  i  -   1 ; d[i].R  =  i  +   1 ;} d[ 0 ].L  =  m; d[m].R  =   0 ; nodes  =  m;
    re1(i, n) rowh[i] 
=   - 1 ;
    re1(i, m) cols[i] 
=   0 ;
}
void  add_node( int  r,  int  c)
{
    cols[c]
++ ; d[ ++ nodes].r  =  r; d[nodes].c  =  c; d[nodes].U  =  d[c].U; d[nodes].D  =  c; d[c].U  =  nodes; d[d[nodes].U].D  =  nodes;
    
int  rh  =  rowh[r];  if  (rh  ==   - 1 ) d[nodes].L  =  d[nodes].R  =  rowh[r]  =  nodes;  else  {
        d[nodes].L 
=  d[rh].L; d[nodes].R  =  rh; d[rh].L  =  nodes; d[d[nodes].L].R  =  nodes;
    }
}
void  init()
{
    freopen(
" zhzyx.in " " r " , stdin);
    
char  ch;
    re(i, S) {
        re(j, i
+ 1 ) a[i][j]  =  getchar();
        ch 
=  getchar();
    }
    fclose(stdin);
}
void  delLR( int  x)
{
    d[d[x].L].R 
=  d[x].R; d[d[x].R].L  =  d[x].L;
}
void  resuLR( int  x)
{
    d[d[x].L].R 
=  d[d[x].R].L  =  x;
}
void  delUD( int  x)
{
    d[d[x].U].D 
=  d[x].D; d[d[x].D].U  =  d[x].U;
}
void  resuUD( int  x)
{
    d[d[x].U].D 
=  d[d[x].D].U  =  x;
}
void  delcol( int  x)
{
    delLR(x); 
for  ( int  i = d[x].D; i  !=  x; i = d[i].D)  for  ( int  j = d[i].R; j  !=  i; j = d[j].R) {cols[d[j].c] -- ; delUD(j);}
}
void  resucol( int  x)
{
    
for  ( int  i = d[x].U; i  !=  x; i = d[i].U)  for  ( int  j = d[i].L; j  !=  i; j = d[j].L) {resuUD(j); cols[d[j].c] ++ ;} resuLR(x);
}
void  prepare()
{
    init_d();
    len[
0 =   3 set ( 0 0 0 0 );  set ( 0 1 0 1 );  set ( 0 2 1 0 );
    len[
1 =   3 set ( 1 0 0 0 );  set ( 1 1 0 1 );  set ( 1 2 1 1 );
    len[
2 =   3 set ( 2 0 0 0 );  set ( 2 1 1 0 );  set ( 2 2 1 1 );
    len[
3 =   3 set ( 3 0 0 0 );  set ( 3 1 1 0 );  set ( 3 2 1 - 1 );
    len[
4 =   4 set ( 4 0 0 0 );  set ( 4 1 0 1 );  set ( 4 2 0 2 );  set ( 4 3 0 3 );
    len[
5 =   4 set ( 5 0 0 0 );  set ( 5 1 1 0 );  set ( 5 2 2 0 );  set ( 5 3 3 0 );
    len[
6 =   4 set ( 6 0 0 0 );  set ( 6 1 0 1 );  set ( 6 2 0 2 );  set ( 6 3 1 0 );
    len[
7 =   4 set ( 7 0 0 0 );  set ( 7 1 0 1 );  set ( 7 2 0 2 );  set ( 7 3 1 2 );
    len[
8 =   4 set ( 8 0 0 0 );  set ( 8 1 1 0 );  set ( 8 2 1 1 );  set ( 8 3 1 2 );
    len[
9 =   4 set ( 9 0 0 0 );  set ( 9 1 1 0 );  set ( 9 2 1 - 1 );  set ( 9 3 1 - 2 );
    len[
10 =   4 set ( 10 0 0 0 );  set ( 10 1 0 1 );  set ( 10 2 1 0 );  set ( 10 3 2 0 );
    len[
11 =   4 set ( 11 0 0 0 );  set ( 11 1 0 1 );  set ( 11 2 1 1 );  set ( 11 3 2 1 );
    len[
12 =   4 set ( 12 0 0 0 );  set ( 12 1 1 0 );  set ( 12 2 2 0 );  set ( 12 3 2 1 );
    len[
13 =   4 set ( 13 0 0 0 );  set ( 13 1 1 0 );  set ( 13 2 2 0 );  set ( 13 3 2 - 1 );
    len[
14 =   4 set ( 14 0 0 0 );  set ( 14 1 0 1 );  set ( 14 2 1 0 );  set ( 14 3 1 1 );
    len[
15 =   5 set ( 15 0 0 0 );  set ( 15 1 1 0 );  set ( 15 2 2 0 );  set ( 15 3 2 1 );  set ( 15 4 2 2 );
    len[
16 =   5 set ( 16 0 0 0 );  set ( 16 1 1 0 );  set ( 16 2 2 0 );  set ( 16 3 2 - 1 );  set ( 16 4 2 - 2 );
    len[
17 =   5 set ( 17 0 0 0 );  set ( 17 1 0 1 );  set ( 17 2 0 2 );  set ( 17 3 1 0 );  set ( 17 4 2 0 );
    len[
18 =   5 set ( 18 0 0 0 );  set ( 18 1 0 1 );  set ( 18 2 0 2 );  set ( 18 3 1 2 );  set ( 18 4 2 2 );
    len[
19 =   5 set ( 19 0 0 0 );  set ( 19 1 0 1 );  set ( 19 2 0 2 );  set ( 19 3 0 3 );  set ( 19 4 1 1 );
    len[
20 =   5 set ( 20 0 0 0 );  set ( 20 1 0 1 );  set ( 20 2 0 2 );  set ( 20 3 0 3 );  set ( 20 4 1 2 );
    len[
21 =   5 set ( 21 0 0 0 );  set ( 21 1 1 - 1 );  set ( 21 2 1 0 );  set ( 21 3 1 1 );  set ( 21 4 1 2 );
    len[
22 =   5 set ( 22 0 0 0 );  set ( 22 1 1 - 2 );  set ( 22 2 1 - 1 );  set ( 22 3 1 0 );  set ( 22 4 1 1 );
    len[
23 =   5 set ( 23 0 0 0 );  set ( 23 1 1 0 );  set ( 23 2 1 1 );  set ( 23 3 2 0 );  set ( 23 4 3 0 );
    len[
24 =   5 set ( 24 0 0 0 );  set ( 24 1 1 0 );  set ( 24 2 1 - 1 );  set ( 24 3 2 0 );  set ( 24 4 3 0 );
    len[
25 =   5 set ( 25 0 0 0 );  set ( 25 1 1 0 );  set ( 25 2 2 0 );  set ( 25 3 2 1 );  set ( 25 4 3 0 );
    len[
26 =   5 set ( 26 0 0 0 );  set ( 26 1 1 0 );  set ( 26 2 2 0 );  set ( 26 3 2 - 1 );  set ( 26 4 3 0 );
    len[
27 =   5 set ( 27 0 0 0 );  set ( 27 1 0 1 );  set ( 27 2 0 2 );  set ( 27 3 1 0 );  set ( 27 4 1 2 );
    len[
28 =   5 set ( 28 0 0 0 );  set ( 28 1 1 0 );  set ( 28 2 1 1 );  set ( 28 3 0 2 );  set ( 28 4 1 2 );
    len[
29 =   5 set ( 29 0 0 0 );  set ( 29 1 0 1 );  set ( 29 2 1 0 );  set ( 29 3 2 0 );  set ( 29 4 2 1 );
    len[
30 =   5 set ( 30 0 0 0 );  set ( 30 1 0 1 );  set ( 30 2 1 1 );  set ( 30 3 2 0 );  set ( 30 4 2 1 );
    len[
31 =   5 set ( 31 0 0 0 );  set ( 31 1 0 1 );  set ( 31 2 0 2 );  set ( 31 3 1 0 );  set ( 31 4 1 1 );
    len[
32 =   5 set ( 32 0 0 0 );  set ( 32 1 0 1 );  set ( 32 2 0 2 );  set ( 32 3 1 1 );  set ( 32 4 1 2 );
    len[
33 =   5 set ( 33 0 0 0 );  set ( 33 1 0 1 );  set ( 33 2 1 0 );  set ( 33 3 1 1 );  set ( 33 4 1 2 );
    len[
34 =   5 set ( 34 0 0 0 );  set ( 34 1 0 1 );  set ( 34 2 1 - 1 );  set ( 34 3 1 0 );  set ( 34 4 1 1 );
    len[
35 =   5 set ( 35 0 0 0 );  set ( 35 1 0 1 );  set ( 35 2 1 0 );  set ( 35 3 1 1 );  set ( 35 4 2 0 );
    len[
36 =   5 set ( 36 0 0 0 );  set ( 36 1 0 1 );  set ( 36 2 1 0 );  set ( 36 3 1 1 );  set ( 36 4 2 1 );
    len[
37 =   5 set ( 37 0 0 0 );  set ( 37 1 1 0 );  set ( 37 2 1 1 );  set ( 37 3 2 0 );  set ( 37 4 2 1 );
    len[
38 =   5 set ( 38 0 0 0 );  set ( 38 1 1 - 1 );  set ( 38 2 1 0 );  set ( 38 3 2 - 1 );  set ( 38 4 2 0 );
    len[
39 =   5 set ( 39 0 0 0 );  set ( 39 1 0 1 );  set ( 39 2 0 2 );  set ( 39 3 1 2 );  set ( 39 4 1 3 );
    len[
40 =   5 set ( 40 0 0 0 );  set ( 40 1 0 1 );  set ( 40 2 0 2 );  set ( 40 3 1 - 1 );  set ( 40 4 1 0 );
    len[
41 =   5 set ( 41 0 0 0 );  set ( 41 1 0 1 );  set ( 41 2 1 1 );  set ( 41 3 1 2 );  set ( 41 4 1 3 );
    len[
42 =   5 set ( 42 0 0 0 );  set ( 42 1 0 1 );  set ( 42 2 1 - 2 );  set ( 42 3 1 - 1 );  set ( 42 4 1 0 );
    len[
43 =   5 set ( 43 0 0 0 );  set ( 43 1 1 0 );  set ( 43 2 2 0 );  set ( 43 3 2 1 );  set ( 43 4 3 1 );
    len[
44 =   5 set ( 44 0 0 0 );  set ( 44 1 1 0 );  set ( 44 2 2 - 1 );  set ( 44 3 2 0 );  set ( 44 4 3 - 1 );
    len[
45 =   5 set ( 45 0 0 0 );  set ( 45 1 1 0 );  set ( 45 2 1 1 );  set ( 45 3 2 1 );  set ( 45 4 3 1 );
    len[
46 =   5 set ( 46 0 0 0 );  set ( 46 1 1 - 1 );  set ( 46 2 1 0 );  set ( 46 3 2 - 1 );  set ( 46 4 3 - 1 );
    len[
47 =   5 set ( 47 0 0 0 );  set ( 47 1 1 - 1 );  set ( 47 2 1 0 );  set ( 47 3 1 1 );  set ( 47 4 2 0 );
    len[
48 =   5 set ( 48 0 0 0 );  set ( 48 1 1 0 );  set ( 48 2 1 1 );  set ( 48 3 2 1 );  set ( 48 4 2 2 );
    len[
49 =   5 set ( 49 0 0 0 );  set ( 49 1 1 - 1 );  set ( 49 2 1 0 );  set ( 49 3 2 - 2 );  set ( 49 4 2 - 1 );
    len[
50 =   5 set ( 50 0 0 0 );  set ( 50 1 0 1 );  set ( 50 2 1 1 );  set ( 50 3 1 2 );  set ( 50 4 2 2 );
    len[
51 =   5 set ( 51 0 0 0 );  set ( 51 1 0 1 );  set ( 51 2 1 - 1 );  set ( 51 3 1 0 );  set ( 51 4 2 - 1 );
    len[
52 =   5 set ( 52 0 0 0 );  set ( 52 1 0 1 );  set ( 52 2 0 2 );  set ( 52 3 0 3 );  set ( 52 4 1 0 );
    len[
53 =   5 set ( 53 0 0 0 );  set ( 53 1 0 1 );  set ( 53 2 0 2 );  set ( 53 3 0 3 );  set ( 53 4 1 3 );
    len[
54 =   5 set ( 54 0 0 0 );  set ( 54 1 1 - 3 );  set ( 54 2 1 - 2 );  set ( 54 3 1 - 1 );  set ( 54 4 1 0 );
    len[
55 =   5 set ( 55 0 0 0 );  set ( 55 1 1 0 );  set ( 55 2 1 1 );  set ( 55 3 1 2 );  set ( 55 4 1 3 );
    len[
56 =   5 set ( 56 0 0 0 );  set ( 56 1 0 1 );  set ( 56 2 1 0 );  set ( 56 3 2 0 );  set ( 56 4 3 0 );
    len[
57 =   5 set ( 57 0 0 0 );  set ( 57 1 0 1 );  set ( 57 2 1 1 );  set ( 57 3 2 1 );  set ( 57 4 3 1 );
    len[
58 =   5 set ( 58 0 0 0 );  set ( 58 1 1 0 );  set ( 58 2 2 0 );  set ( 58 3 3 0 );  set ( 58 4 3 1 );
    len[
59 =   5 set ( 59 0 0 0 );  set ( 59 1 1 0 );  set ( 59 2 2 0 );  set ( 59 3 3 - 1 );  set ( 59 4 3 0 );
    
int  No0  =   0 , x0, y0, z; re(i, S) re(j, i + 1 ) No[i][j]  =   ++ No0;
    
bool  ff;
    No0 
=   0 ; re(i, T) re(x, S) re(y, x + 1 ) {
        ff 
=   1 ; re(j, len[i]) {
            x0 
=  x  +  PX[i][j]; y0  =  y  +  PY[i][j];
            
if  (x0  <   0   ||  x0  >=  S  ||  y0  <   0   ||  y0  >=  S  ||  x0  <  y0) {ff  =   0 break ;}
        }
        
if  (ff) {
            No0
++ ; pos[No0][ 0 =  i; pos[No0][ 1 =  x; pos[No0][ 2 =  y; _pos[i][x][y]  =  No0;
            re(j, len[i]) {x0 
=  x  +  PX[i][j]; y0  =  y  +  PY[i][j]; add_node(No0, No[x0][y0]);} add_node(No0,  55   +  SSS[i]  -   64 );
        }
    }
    re(i, 
12 ) vst[i]  =   0 ;
    
int  _x, rh;
    re(x, S) re(y, x
+ 1 if  (a[x][y]  !=   ' . ' ) {
        z 
=  a[x][y]  -   65 ;
        
if  ( ! vst[z]) {
            vst[z] 
=   1 ;
            re3(i, LL[z], RR[z]) {
                ff 
=   1 ; re(j, len[i]) {
                    x0 
=  x  +  PX[i][j]; y0  =  y  +  PY[i][j];
                    
if  (x0  <   0   ||  x0  >=  S  ||  y0  <   0   ||  y0  >=  S  ||  x0  <  y0  ||  a[x0][y0]  !=  a[x][y]) {ff  =   0 break ;}
                }
                
if  (ff) {
                    _x 
=  _pos[i][x][y]; rh  =  rowh[_x]; delcol(d[rh].c);
                    
for  ( int  j = d[rh].R; j  !=  rh; j = d[j].R) delcol(d[j].c);
                    
break ;
                }
            }
        }
    }
}
bool  dfs( int  dep)
{
    
if  ( ! d[ 0 ].R) {res_len  =  dep;  return   1 ;}
    
int  mins  =  INF, c0;  for  ( int  i = d[ 0 ].R; i; i = d[i].R)  if  ( ! cols[i])  return   0 else   if  (cols[i]  <  mins) {mins  =  cols[i]; c0  =  i;}
    delcol(c0);
    
for  ( int  i = d[c0].D; i  !=  c0; i = d[i].D) {
        
for  ( int  j = d[i].R; j  !=  i; j = d[j].R) {delcol(d[j].c);}
        res[dep] 
=  d[i].r;  if  (dfs(dep  +   1 ))  return   1 ;
        
for  ( int  j = d[i].L; j  !=  i; j = d[j].L) resucol(d[j].c);
    }
    resucol(c0);
    
return   0 ;
}
void  solve()
{
    
int  x, y, z;
    
if  (dfs( 0 )) {
        re(i, res_len) {
            z 
=  pos[res[i]][ 0 ]; x  =  pos[res[i]][ 1 ]; y  =  pos[res[i]][ 2 ];
            re(j, len[z]) a[x 
+  PX[z][j]][y  +  PY[z][j]]  =  SSS[z];
        }
    } 
else  res_len  =   - 1 ;
}
void  pri()
{
    freopen(
" zhzyx.out " " w " , stdout);
    
if  (res_len  ==   - 1 ) puts( " No solution " );  else  re(i, S) {re(j, i + 1 ) putchar(a[i][j]); puts( "" );}
    fclose(stdout);
}
int  main()
{
    init();
    prepare();
    solve();
    pri();
    
return   0 ;
}

你可能感兴趣的:(NOI2005 智慧珠游戏)