USACO 3.2 Magic Squares

USACO 3.2 Magic Squares

 BFS搜索题。代码写的比较乱,用一个set来存储已经访问过的结点。analysis中的标程有不少可以学习的地方,如几个操作的变换,用转换数组来写,代码清晰明了,encode方法就省去了set。我通过保存整个树来输出解,标程通过反向操作,来输出解,做法很巧妙。

#include  < iostream >
#include 
< fstream >
#include 
< set >
#include 
< queue >

using   namespace  std;

ifstream fin(
" msquare.in " );
ofstream fout(
" msquare.out " );

#ifdef _DEBUG
#define  out cout
#define  in cin
#else
#define  out fout
#define  in fin
#endif

int  final[ 8 ];
set < int > visited;
char  result[ 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 + 1 ];

struct  queue_node{
    
int  current[ 8 ];
    queue_node 
* parent;
    
char  op;
};

void  op( int   * current, char  c)
{
    
int  tmp;
    
switch (c){
        
case   ' A ' :
            
for ( int  i = 0 ;i < 4 ; ++ i)
                swap(current[i],current[
7 - i]);
            
break ;
        
case   ' B ' :
            tmp 
=  current[ 3 ];
            
for ( int  i = 3 ;i >= 1 ; -- i)
                current[i] 
=  current[i - 1 ];
            current[
0 =  tmp;
            tmp 
=  current[ 4 ];
            
for ( int  i = 4 ;i <= 6 ; ++ i)
                current[i] 
=  current[i + 1 ];
            current[
7 =  tmp;
            
break ;
        
case   ' C ' :
            tmp 
=  current[ 6 ];
            current[
6 =  current[ 5 ];
            current[
5 =  current[ 2 ];
            current[
2 =  current[ 1 ];
            current[
1 =  tmp;
            
break ;
    }
}

int  cur_value( int   * cur)
{
    
int  res  =   0 ;
    
for ( int  i = 0 ;i < 8 ; ++ i){
        res
*= 10 ;
        res
+= cur[i];
    }

    
return  res;
}


void  solve()
{
    
for ( int  i = 0 ;i < 8 ; ++ i){
        
in >> final[i];
    }

    queue
< queue_node *>  q;
    queue_node 
* node  =   new  queue_node;
    
for ( int  i = 0 ;i < 8 ; ++ i)
        node
-> current[i]  =  i + 1 ;

    node
-> parent  =  NULL;

    q.push(node);

    
while ! q.empty() ){
        queue_node 
* node  =  q.front();
        q.pop();

        
int  cur  =  cur_value(node -> current);
        
if ( visited.find( cur)  !=  visited.end())
            
continue ;
        visited.insert(cur);

        
bool  ok  =   true ;
        
for ( int  i = 0 ;i < 8 ; ++ i){
            
if (node -> current[i] != final[i]){
                ok 
=   false ;
                
break ;
            }
        }

        
if (ok){
            
int  i  =   0 ;
            
while (node -> parent != NULL){
                result[i
++ =  node -> op;
                node
= node -> parent;
            }

            
if (i == 0 ){
                
out << 0 << endl << endl;
                exit(
0 );
            }

            
out << i << endl;

            
int  j;
            i
-- ;
            
for (j = 0 ;i >= 0 ;i -- ,j ++ ){
                
out << result[i];
                
if (j % 60 == 59 out << endl;
            }
            
            
if (j % 60 != 0 )
                
out << endl;

            exit(
0 );
        }

        
for ( char  c = ' A ' ;c <= ' C ' ; ++ c){
            queue_node 
*  n  =   new  queue_node;
            memcpy(n
-> current,node -> current, sizeof (node -> current));
            op(n
-> current,c);
            n
-> op  =  c;
            n
-> parent  =  node;
            q.push(n);
        }
    }
}

int  main( int  argc, char   * argv[])
{
    solve(); 
    
return   0 ;
}


你可能感兴趣的:(USACO 3.2 Magic Squares)