题目链接: 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 ;
}
#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 ;
}