poj 2488 A Knight's Journey (dfs)

题目链接:  http://poj.org/problem?id=2488

题意:

    棋子按象棋中马的方式在棋盘中跳,给定棋盘的大小,求能使棋子走遍每个棋格且每个棋格只走一次的方案,要求是字典顺序最小的方案。

 

    看到要求字典顺序最小,便单纯的想dfs出所有解然后字典排序。看了解体报告才知道自己多么幼稚......可以先定义好棋子跳动的顺序,使其为字典最小序列。

代码:

 

#include < iostream >
#include
< cstring >
using   namespace  std ;

int  c, r ;
bool  b[ 30 ][ 30 ], bl ;
char  str[ 100 ] ;
int  move[ 8 ][ 2 = {{ - 2 - 1 }, { - 2 1 }, { - 1 - 2 }, { - 1 2 }, { 1 - 2 }, { 1 2 }, { 2 - 1 }, { 2 1 }} ;

void  dfs( int  x,  int  y,  int  step,  int  k){
    
if (bl)  return  ;             // 若找到了满足的解,则直接返回
     int  xi, yi ;
    str[k] 
=   ' A '   +  x ;
    str[k
+ 1 =   ' 1 '   +  y ;
    
if (step == r * c){               // 走完全盘则标记成功
        bl  =   true  ;
        
return  ;
    }
    
for ( int  i = 0 ; i < 8 ; i ++ ){
        xi 
=  x  +  move[i][ 0 ] ;
        yi 
=  y  +  move[i][ 1 ] ;
        
if (xi >= 0 && yi >= 0 && xi < r && yi < c){
            
if ( ! b[xi][yi]){
                b[xi][yi] 
=   true  ;
                dfs(xi, yi, step
+ 1 , k + 2 ) ;
                b[xi][yi] 
=   false  ;              // 回溯
            }
        }
    }
}

int  main(){
    
int  n, t  =   1  ;
    cin 
>>  n ;
    
while (n -- ){
        cin 
>>  c  >>  r ;
        memset(b, 
false sizeof (b)) ;
        b[
0 ][ 0 =   true  ;
        bl 
=   false  ;
        dfs(
0 0 1 0 ) ;
        cout 
<<   " Scenario # "   <<  t  <<   " : "   <<  endl ;
        
if ( ! bl) cout  <<   " impossible "   <<  endl ;
        
else {
            str[
2 * r * c]  =   0  ;           // 必须封好字符串!WA了好几次
            cout  <<  str  <<  endl ;
        }
        cout 
<<  endl ;
        t 
++  ;
    }
    
return   0  ;
}

 

你可能感兴趣的:(poj)