题目链接:http://poj.org/problem?id=2488
题目分析:
题目大意就是一个国际象棋的骑士,也就是相当于中国象棋的马,行走是以日字的,现给定一个p、q,表示
p行(按照数字排列),q列(按照字母排列);现随意选定一个起点,问是否能够不重复的走过每一个格子,不能
输出impossible,能输出按字母序最小的行走序列,可以参照样例理解。
虽然是比较简单的搜索题,但需要注意下一下几点:
1. 因为是输出字母序最小的,如果能够遍历,那么肯定是由左上角的格子出发,所以起始点是确定的;
2. 主要搜索的顺序,因为是字母排在前面,所以搜索为:(前面的行,后面是列)
dir[8][2] = {{1,-2}, {-1,-2}, {-2,-1}, {2,-1}, {-2,1}, {2,1}, {-1,2}, {1,2}} ;
<span style="font-size:18px;">#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std ;
//
int dir[8][2] = {{1,-2}, {-1,-2}, {-2,-1}, {2,-1}, {-2,1}, {2,1}, {-1,2}, {1,2}} ;
int res[100][2], len ;
int p, q ;
bool used[100][100] ;
//
bool dfs(int y, int x, int dep){
if( dep == len ) return true ;
for( int i = 0; i < 8; i++ ){
int dx = x + dir[i][0] ;
int dy = y + dir[i][1] ;
if( dx <= 0 || dx > p ) continue ;
if( dy <= 0 || dy > q ) continue ;
res[dep+1][1] = dx, res[dep+1][0] = dy ;
if( !used[dx][dy] ){
used[dx][dy] = true ;
if ( dfs(dy, dx, dep+1) ) return true ;
used[dx][dy] = false ;
}
}
return false ;
}
//
int main(){
///freopen("1234.in", "r", stdin) ;
int n ;
scanf("%d", &n) ;
for( int cas = 1; cas <= n; cas++ ){
scanf("%d%d",&p, &q) ;
bool judge = false ;
memset(res, 0, sizeof(res)) ;
memset(used, 0, sizeof(used)) ;
res[1][0] = 1, res[1][1] = 1 ;
used[1][1] = true ;
len = p * q ;
judge = dfs(1, 1, 1) ;
if( judge ){
cout << "Scenario #" << cas << ":\n" ;
for( int t = 1; t <= len; t++ ){
char ch = 'A' + res[t][0] - 1 ;
cout << ch << res[t][1] ;
}
cout << "\n\n" ;
}
if( judge ) continue ;
cout << "Scenario #" << cas << ":\n" << "impossible\n\n" ;
}
return 0 ;
}
</span>