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}, {-21}, {-1-2}, {-12}, {1-2}, {12}, {2-1}, {21}} ;

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, 
falsesizeof(b)) ;
        b[
0][0= true ;
        bl 
= false ;
        dfs(
0010) ;
        cout 
<< "Scenario #" << t << ":" << endl ;
        
if(!bl) cout << "impossible" << endl ;
        
else{
            str[
2*r*c] = 0 ;          //必须封好字符串!WA了好几次
            cout << str << endl ;
        }
        cout 
<< endl ;
        t 
++ ;
    }
    
return 0 ;
}
原文地址:https://www.cnblogs.com/xiaolongchase/p/2161431.html