马的遍历问题,明天会考吗?给出一种解法!

ppjob 2003-10-11 11:59:51
马的遍历问题。
在N*M的棋盘中,马只能走日字。马从位置(x,y)处出发,把棋盘的每一格都走一次,且只走一次。找出所有路径。
算法分析:深度优先搜索法

参考程序(设棋盘为5*4)
program goaround;
const
n=5;m=4;
fx:array[1..8,1..2]of -2..2=((1,2),(2,1),(2,-1),(1,-2),(-1,-2),(-2,-1),(-2,1),(-1,2)); {八个方向增量代表马的8种走法}
var
dep,i:byte;
x,y:byte;
cont:integer; {统计总数}
a:array[1..n,1..m]of byte; {记录走法数组}

procedure output; {输出,并统计总数}
var x,y:byte;
begin
cont:=cont+1; writeln;
writeln('count=',cont);
for y:=1 to n do begin
for x:=1 to m do write(a[y,x]:3); writeln;
end;
readln;
end;

procedure find(y,x,dep:byte);
var
i,xx,yy:integer;
begin
for i:=1 to 8 do{穷尽8种走法}
begin
xx:=x+fx[i,1];
yy:=y+fx[i,2]; {加上方向增量,形成新的坐标}
if ((xx in [1..m])and(yy in [1..n]))and(a[yy,xx]=0) then
{判断新坐标是否出界,是否已走过?}
begin
a[yy,xx]:=dep; {走向新的坐标}
if (dep=n*m) then output
else find(yy,xx,dep+1); {从新坐标出发,递归下一层}
a[yy,xx]:=0 {回溯,恢复未走标志}
end;
end;
end;

begin
cont:=0;
fillchar(a,sizeof(a),0);
dep:=1;
writeln('input y,x');readln(y,x);
if (y>n) or(x>m) then begin writeln('x,y error!');halt;end;
a[y,x]:=1;
find(y,x,2);
if cont=0 then writeln('No answer!') else write('The End!');
readln;
end.
...全文
81 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
知平软件 2003-10-12
  • 打赏
  • 举报
回复
/**********************************************************
* horse.c - 马遍历棋盘的问题(中国象棋)
* 具体问题描述:在8 * 8方格的棋盘上, 从任意指定的方格出发,
* 为马寻找一条走遍棋盘每一个并且只经过一次的一条路径
*********************************************************/
#include <stdio.h>

#define N 8 /* 棋盘大小 */

static int board[N][N]; /* 棋盘 */

typedef struct _position
{
int x; /* 行 */
int y; /* 列 */
}position, *pposition; /* 棋盘里的任意位置 */

void HorseTraversel(pposition Pos);
pposition FindNextPos(pposition Pos);
int EnumExist(pposition Pos);
void PrintResult();

int Step; /* */

int main()
{
int iRow,
iColumn;
position psStart = {0, 0};

Step = 1;

for ( iRow = 0; iRow < N; iRow++ )
{
for ( iColumn = 0; iColumn < N; iColumn++ )
board[iRow][iColumn] = 0;
}

HorseTraversel(&psStart);
PrintResult();
printf("\n");

return 0;
}

/* */
void HorseTraversel(pposition ppsCurrent)
{
if ( Step >= (N * N) )
{
return;
}

board[ppsCurrent->x][ppsCurrent->y] = Step++;

HorseTraversel(FindNextPos(ppsCurrent));
}

int iStepX[N] = {1, 2, 1, 2, -1, -2, -1, -2};
int iStepY[N] = {2, 1, -2, -1, 2, 1, -2, -1};

//#define MIN(x, y) (((x) < (y)) ? (x) : (y))

/* */
pposition FindNextPos(pposition ppsCurrent)
{
pposition ppsNextPos;
int iminiMumExist = 9;
int iCurExists;
int i;
int iNextPos;

//psNextPos = *ppsCurrent;
ppsNextPos = (pposition)malloc(sizeof(position));


for ( i = 0; i < N; i++ )
{
ppsNextPos->x = ppsCurrent->x + iStepX[i];
ppsNextPos->y = ppsCurrent->y + iStepY[i];

if ( !(iCurExists = EnumExist(ppsNextPos)) )
continue;
//miniMumExist = MIN(miniMumExist,
// EnumExist(&psPosition));
if ( iminiMumExist > iCurExists )
{
iNextPos = i;
iminiMumExist = iCurExists;
}
}

ppsNextPos->x = ppsCurrent->x + iStepX[iNextPos];
ppsNextPos->y = ppsCurrent->y + iStepY[iNextPos];

return ppsNextPos;
}

#define isValidRow(x) ( ((x) >= 0) && ((x) < N) )
#define isValidColumn(x) isValidRow(x)

int EnumExist(pposition ppsPosition)
{
int i,
iRow,
iColumn,
iTotalExists = 0;

if ( !isValidRow(ppsPosition->x) ||
!isValidColumn(ppsPosition->y) ||
board[ppsPosition->x][ppsPosition->y] )
return iTotalExists;

for ( i = 0; i < N ; i++ )
{
iRow = ppsPosition->x + iStepX[i];
iColumn = ppsPosition->y + iStepY[i];

if ( isValidRow(iRow) &&
isValidColumn(iColumn) &&
(board[iRow][iColumn] == 0) )
iTotalExists++;
}

return iTotalExists;
}

/* */
void PrintResult()
{
int iRow;
int iColumn;

for ( iRow = 0; iRow < N; iRow++ )
{
for ( iColumn = 0; iColumn < N; iColumn++ )
printf("|---");

printf("|\n");

for ( iColumn = 0; iColumn < N; iColumn++ )
printf("|%2d ", board[iRow][iColumn]);

printf("|\n");
}

for ( iColumn = 0; iColumn < N; iColumn++ )
printf("|---");
}

ManZY 2003-10-12
  • 打赏
  • 举报
回复
什么呀!
怎么不用C语言给出算法?!!!!
考试一般考C语言的!
仔细研究个C语言的算法吧!
liuhelin 2003-10-12
  • 打赏
  • 举报
回复
伏伏 2003-10-12
  • 打赏
  • 举报
回复
program goaround;
const
n=5;m=4;
fx:array[1..8,1..2]of -2..2=((1,2),(2,1),(2,-1),(1,-2),(-1,-2),(-2,-1),(-2,1),(-1,2)); {八个方向增量代表马的8种走法}
var
dep,i:byte;
x,y:byte;
cont:integer; {统计总数}
a:array[1..n,1..m]of byte; {记录走法数组}

procedure output; {输出,并统计总数}
var x,y:byte;
begin
cont:=cont+1; writeln;
writeln('count=',cont);
for y:=1 to n do begin
for x:=1 to m do write(a[y,x]:3); writeln;
end;
readln;
end;

procedure find(y,x,dep:byte);
var
i,xx,yy:integer;
begin
for i:=1 to 8 do{穷尽8种走法}
begin
xx:=x+fx[i,1];
yy:=y+fx[i,2]; {加上方向增量,形成新的坐标}
if ((xx in [1..m])and(yy in [1..n]))and(a[yy,xx]=0) then
{判断新坐标是否出界,是否已走过?}
begin
a[yy,xx]:=dep; {走向新的坐标}
if (dep=n*m) then output
else find(yy,xx,dep+1); {从新坐标出发,递归下一层}
a[yy,xx]:=0 {回溯,恢复未走标志}
end;
end;
end;

begin
cont:=0;
fillchar(a,sizeof(a),0);
dep:=1;
writeln('input y,x');readln(y,x);
if (y>n) or(x>m) then begin writeln('x,y error!');halt;end;
a[y,x]:=1;
find(y,x,2);
if cont=0 then writeln('No answer!') else write('The End!');
readln;
end.

2,948

社区成员

发帖
与我相关
我的任务
社区描述
就计算机等级考试、软件初、中、高级不同级别资格考试相关话题交流经验,共享资源。
c1认证c4javac4前端 技术论坛(原bbs)
社区管理员
  • 软件水平考试社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧