您的位置:首页 > 其它

POJ 2488 A Knight's Journey

2014-07-31 19:08 218 查看
题目大意:

考察马能否周游一遍棋盘上所有的格子一遍(不重复经过同一个格子),有t个测例,每个测例都会给出棋盘大小p×q,其中1 ≤ pq ≤ 26,其中p表示的棋盘的行(1 ~ 8),q表示棋盘的列数(A ~ A+q-1),对于每个测例如果可以周游就输出一条周游路线,路线中先后包括一路上经过的格子的代号,比如"A1B2E4"就代表先后经过了1行A列、2行B列、4行E列,如果存在多条路线,则输出字典序最小的那条路线,如果不存在则输出"impossible"。

题目链接

注释代码:

/*
* Problem ID : POJ 2488 A Knight's Journey
* Author     : Lirx.t.Una
* Language   : C++
* Run Time   : 0 ms
* Run Memory : 132 KB
*/

#include <iostream>
#include <cstring>
#include <cstdio>

//棋盘最大宽度(3×9=27>26)
#define	MAXW	8
//最大周游步数25步
#define	MAXSTP	26

//程序中行为字母,列为数字
int		r, c;//棋盘的行数和列数
int		stp;//当前马做过的步数
bool	vis[MAXW][MAXW];//棋盘上的格子是否被访问过

//深搜的时候按照这个顺序(方向)进行搜索,可以保证输出一定是字典序最小的
char	dx[9] = { 0, -2, -2, -1, -1,  1, 1,  2, 2 };
char	dy[9] = { 0, -1,  1, -2,  2, -2, 2, -1, 1 };

//保存最终周游路线,是总步数的两倍,最后一位留给'\0'
//由于要求字典序最小输出,并且所有格子必须要经过一遍
//因此第一个访问的必定是格子A1
char	path[ 1 + ( MAXSTP << 1 ) ] = "A1";

bool
dfs( int x, int y ) {//按照dx、dy的顺序进行深搜

int		i, j;//计数变量
int		xx, yy;//x、y表示当前位置,xx、yy表示下一个位置

for ( i = 1; i < 9; i++ ) {

xx = x + dx[i];
yy = y + dy[i];

if ( xx < 1 || xx > r || yy < 1 || yy > c || vis[xx][yy] )
continue;

stp++;//下一位置合法,所以先试探性走一步
vis[xx][yy]  = true;

j = stp << 1;//将该位置的坐标记录到路径当中
path[j - 2] = xx + 'A' - 1;
path[j - 1] = yy + '0';

//如果步数刚好达到格子的总数则表示找到周游路线成功退出即可
if ( stp == r * c ) return true;
//否则就代表还没走完所有格子,所以需要继续深搜
if ( dfs( xx, yy ) ) return true;

vis[xx][yy] = false;//如果行不通则需要将刚刚走的一步收回,试探其它走法
stp--;//步数也需要重新收回
}

return false;//所有走法都试过了还不行
}

int
main() {

int		t, iscn;

int		i;//技术变量

scanf("%d", &t);
iscn = 0;

while ( t-- ) {

scanf("%d%d", &c, &r);//程序中字母表示行数字表示列
printf("Scenario #%d:\n", ++iscn);

if ( 1 == r && 1 == c ) {//特殊情况

puts("A1\n");
continue;
}

if ( r > 8 || c > 8 || r < 3 || c < 3 ) {//棋盘本身限制

puts("impossible\n");
continue;
}

//进行深搜
memset(vis, false, sizeof(vis));

stp = 1;
vis[1][1] = true;
if ( !dfs( 1, 1 ) ) {

puts("impossible\n");
continue;
}

path[stp << 1] = '\0';
printf("%s\n\n", path);//输出测例之间空一行
}

return 0;
}
无注释代码:

#include <iostream>
#include <cstring>
#include <cstdio>

#define	MAXW	8
#define	MAXSTP	26

int		r, c;
int		stp;
bool	vis[MAXW][MAXW];

char	dx[9] = { 0, -2, -2, -1, -1,  1, 1,  2, 2 };
char	dy[9] = { 0, -1,  1, -2,  2, -2, 2, -1, 1 };

char	path[ 1 + ( MAXSTP << 1 ) ] = "A1";

bool
dfs( int x, int y ) {

int		i, j;
int		xx, yy;

for ( i = 1; i < 9; i++ ) {

xx = x + dx[i];
yy = y + dy[i];

if ( xx < 1 || xx > r || yy < 1 || yy > c || vis[xx][yy] )
continue;

stp++;
vis[xx][yy]  = true;

j = stp << 1;
path[j - 2] = xx + 'A' - 1;
path[j - 1] = yy + '0';

if ( stp == r * c ) return true;
if ( dfs( xx, yy ) ) return true;

vis[xx][yy] = false;
stp--;
}

return false;
}

int
main() {

int		t, iscn;

int		i;

scanf("%d", &t);
iscn = 0;

while ( t-- ) {

scanf("%d%d", &c, &r);
printf("Scenario #%d:\n", ++iscn);

if ( 1 == r && 1 == c ) {

puts("A1\n");
continue;
}

if ( r > 8 || c > 8 || r < 3 || c < 3 ) {

puts("impossible\n");
continue;
}

memset(vis, false, sizeof(vis));

stp = 1;
vis[1][1] = true;
if ( !dfs( 1, 1 ) ) {

puts("impossible\n");
continue;
}

path[stp << 1] = '\0';
printf("%s\n\n", path);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: