USACO 1.4 The Clocks

USACO 1.4 The Clocks

4次同一操作等效于没有操作,操作的顺序不影响结果。
用迭代加深搜索解(貌似效率不高),代码如下:

#include  < iostream >
#include 
< fstream >
#include 
< string >

using   namespace  std;

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

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

// op[i][j]为操作i对第j个时钟增加的小时数
int  ops[ 9 ][ 9 ];

string  op[ 9 =  {
    
" ABDE " , " ABC " , " BCEF " , " ADG " , " BDEFH " , " CFI " , " DEGH " , " GHI " , " EFHI "
};

// clocks当前时钟的状态
int  clocks[ 9 ];
// 当前的操作序列
int  cur_ops[ 9 ];

void  pre()
{
    memset(ops,
0 , sizeof (ops) );
    memset(cur_ops,
0 , sizeof (cur_ops));

    
for ( int  i = 0 ;i < 9 ; ++ i){
        
for ( int  j = 0 ;j < op[i].size(); ++ j){
            ops[i][op[i][j]
- ' A ' =   3 ;
        }
    }

}

// 执行clocks操作序列
void  do_ops()
{
    
for ( int  i = 0 ;i < 9 ; ++ i){
        
if (cur_ops[i] != 0 )
            
for ( int  j = 0 ;j < 9 ; ++ j){
                clocks[j]
+= ops[i][j] * cur_ops[i];
                clocks[j]
%= 12 ;
            }
    }
}

// i为当前到达的操作编号
void  dfs( int  i,  int  cur_depth, int  max_dep)
{
    
// 到达迭代加深搜索的最大深度或i超过最大
     if (cur_depth > max_dep || i > 9 )
        
return ;    

    
if (cur_depth == max_dep){
        
        
// 保存当前clocks状态
         int  saved[ 9 ];
        memcpy(saved,clocks,
sizeof (clocks));

        do_ops();

        
bool  valid  =   true ;
        
for ( int  i = 0 ;i < 9 ; ++ i){
            
if (clocks[i] != 0 ){
                valid 
=   false ;
                
break ;
            }
        }

        
if (valid){
            
// 时钟全为0,到达可行解
             bool  first  =   true ;
            
for ( int  i = 0 ;i < 9 ; ++ i){
                
if (cur_ops[i] != 0 ){
                    
int  t  =  cur_ops[i];
                    
while (t -- ){
                        
if (first){
                            
out << i + 1 ;
                            first 
=   false ;
                        }
else {
                            
out << "   " << i + 1 ;
                        }
                    }
                }
            }

            
out << endl;
            exit(
0 );
        }
else {
            
// 恢复时钟
            memcpy(clocks,saved, sizeof (saved));
            
return ;
        }
    }

    
for ( int  inc = 3 ;inc >= 0 ;inc -- ){
        
// 因为要求最小的序列,优先多分配当前i,再分配后续更大的号
       if (cur_depth + inc <= max_dep && cur_ops[i] + inc < 4 ){
          cur_ops[i]
+= inc;
          dfs(i
+ 1 ,cur_depth + inc,max_dep);
          cur_ops[i]
-= inc;
      } 
    }
}

void  solve()
{
    pre();

    
for ( int  i = 0 ;i < 9 ; ++ i){
        
in >> clocks[i];
        clocks[i]
%= 12 ;
    }


    
for ( int  d  =   0 ;d <= 3 * 9 ; ++ d){
        dfs(
0 , 0 ,d);
    }
}

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


你可能感兴趣的:(USACO 1.4 The Clocks)