Hoj 10020

Hoj 10020
#include  < stdio.h >
#include 
< memory.h >

int   n, m, l, test;
int   mv[ 4 ][ 2 =  {{ 0 - 1 }, { - 1 0 }, { 0 1 }, { 1 0 }, }; // left up right down
int   pow[ 9 =  { 0 1 4 16 64 256 1024 4096 16384 }; // for 4's pow

bool  tu[ 21 ][ 21 ];
int   mym[ 21 ][ 21 ][ 65535 ];
int   f[ 21 ][ 21 ];

struct  nod
{
    
int  x, y, s, cost, step;
};

bool   operator   < (nod a, nod b)
{
    
return  a.x  <  b.x  ||  a.x  ==  b.x  &&  a.y  <  b.y  ||
        a.x 
==  b.x  &&  a.y  ==  b.y  &&  a.s  <  b.s;
}

int  si, sJ;
nod ini;

int  cha( int  x,  int  y)
{
    
if (x  <   0 return   1 ;
    
if (x  >   0 return   3 ;
    
if (y  <   0 return   0 ;
    
if (y  >   0 return   2 ;
}

void  read()
{
    
int  i, x, y, tx, ty;
    scanf(
" %d %d " & si,  & sJ);
    x 
=  si; y  =  sJ;
    
int  ch  =   0 ;
    
for (i  =   0 ; i  <  l  -   1 ; i  ++ )
    {
        scanf(
" %d %d " & tx,  & ty);
        ch 
=  ch  *   4   +  cha(tx  -  x, ty  -  y);
        x 
=  tx; 
        y 
=  ty;
    }
    ini.s 
=  ch;
    ini.x 
=  si; ini.y  =  sJ;
    
int  stone;
    memset(tu, 
0 sizeof (tu));
    scanf(
" %d " & stone);
    
for (i  =   0 ; i  <  stone; i  ++ )
    {
        scanf(
" %d %d " & x,  & y);
        tu[x][y] 
=   1 ;
    }
}

int  open, close, first;
nod q[
1000001 ];

bool  ok(nod t,  int  index)
{
    
short  dx  =  t.x  +  mv[index][ 0 ], dy  =  t.y  +  mv[index][ 1 ];
    
short  x, y;;
    x 
=  t.x;
    y 
=  t.y;
    
for ( int  i  =   0 ; i  <  l  -   1 ; i  ++ )
    {
        x 
=  x  +  mv[ t.s  /  pow[l  -   1   -  i] ][ 0 ];
        y 
=  y  +  mv[ t.s  /  pow[l  -   1   -  i] ][ 1 ];
        
if (x  ==  dx  &&  y  ==  dy)  return   false ;
        t.s 
=  t.s  %  pow[l  -   1   -  i];
    }
    
return   true ;
}

void  change( int   & ch,  int  i)
{
    ch 
=  ch  >>   2 ;
    ch 
+=  ((i  +   2 %   4 *  pow[l  -   1 ];
}

bool  check(nod t)
{
    
short  xx  =  t.x, yy  =  t.y;
    
if (xx  <   1   ||  xx  >  n  ||  yy  <   1   ||  yy  >  m)  return   false ;
    
if (tu[xx][yy])  return   false ;
    
return   true ;
}

void  heap(nod tp)
{
    nod tmp;
    tmp 
=  q[ ++ open]  =  tp;
    
int  i  =  open, J  =  i  /   2 ;
    
while ( i  >  first)
    {
        
if ( tmp.cost  <  q[J].cost  &&  J  >  first)
        {
            q[i] 
=  q[J];
            i 
=  J;
            J 
=  i  /   2 ;
        }
        
else  
            
break ;
    }
    q[i] 
=  tmp;
}

bool  expend(nod temp)
{
    nod t;
    
for ( int  i  =   0 ; i  <   4 ; i  ++ )
    
if (ok(temp, i))
    {
        t 
=  temp;
        t.x 
+=  mv[i][ 0 ];
        t.y 
+=  mv[i][ 1 ];
        t.step 
++ ;
        
if (t.x  ==   1   &&  t.y  ==   1 return   true ;
        change(t.s, i); 
        
if (check(t)  &&  mym[t.x][t.y][t.s]  !=  test)
        {
            mym[t.x][t.y][t.s] 
=  test;
            t.cost 
=  f[t.x][t.y]  +  t.step;
            heap(t);
        }
    }
    
return   false ;
}

int  bfs()
{
    nod temp;
    close 
=   - 1 ;    open  =   0 ;
    q[
0 =  ini;
    q[
0 ].cost  =  f[ini.x][ini.y];
    q[
0 ].step  =   0 ;
    
if (ini.x  ==   1   &&  ini.y  ==   1 return   0 ;
    mym[ini.x][ini.y][ini.s] 
=  test;
    
int  size;
    
while (close  <  open)
    {
        temp 
=  q[ ++  close];
        first 
=  close  +   1 ;
        
if (expend(temp))  return  temp.step  +   1 ;
    }
    
return   - 1 ;
}

struct  td{ int  x, y;}que[ 1001 ];
bool  ha[ 21 ][ 21 ];
void  pre()
{
    close 
=   - 1 , open  =   0 ;
    memset(ha,
0 , sizeof (ha));
    td t;
    que[
0 ].x  =   1 ;
    que[
0 ].y  =   1 ;
    ha[
1 ][ 1 =   1 ;
    f[
1 ][ 1 =   0 ;
    
while (close  <  open)
    {
        t 
=  que[ ++ close];
        
for ( int  i  =   0 ; i  <   4 ; i  ++ )
        {
            
int  x  =  t.x  +  mv[i][ 0 ], y  =  t.y  +  mv[i][ 1 ];
            
if (x  <   1   ||  x  >  n  ||  y  <   1   ||  y  >  m)  continue ;
            
if (ha[x][y]  ||  tu[x][y])  continue ;
            ha[x][y] 
=   1 ;
            f[x][y] 
=  f[t.x][t.y]  +   1 ;
            que[
++ open].x  =  x;
            que[open].y 
=  y;
        }
    }
}

int  main()
{
    freopen(
" in.txt " , " r " ,stdin);
    test 
=   0 ;
    
while (scanf( " %d %d %d " & n,  & m,  & l), n || m || l)
    {
        read();
        pre();
        
++ test;
        printf(
" Case %d: %d\n " ,test,bfs());
    }
    
while ( 1 );
}

你可能感兴趣的:(Hoj 10020)