大侠们,我遇到了一个马的遍历问题,麻烦帮我一下忙,十分感谢

dimpledashi 2004-12-21 04:04:07
题目如下:
设计程序完成如下要求:在中国象棋棋盘上,对任一位置上放置的一个马,均能选择合适
的路线,使得该棋子能够按象棋的规则不重复的走过棋盘上的每一个位置。
要求:
1.依次输出所走过的各位置的坐标。
2.画出棋盘的图形形式,并在其上动态的标注行走过程。
3.程序能方便的移植到其他规格的棋盘上。
...全文
151 点赞 收藏 11
写回复
11 条回复
双杯献酒 2004年12月22日
不是每种规格的棋盘都能够吧。
回复 点赞
dimpledashi 2004年12月22日
各位大侠,很感谢你们的回答
可是能不能画出棋盘的图形形式,并在其上动态的标注行走过程呢?
回复 点赞
pzcai 2004年12月21日
我问一下_______
| | |
-------
这个格子怎么遍历,其他照搬好了么,所以不是所有棋盘格式都能的
回复 点赞
Bread_0053 2004年12月21日
看来今天写不出来了,有个算法大家参考。。。。
1将原图G按某种方式分成m个子图G1,G2,…,Gm
2在每个子图Gi中,找出它们的一个顶点覆盖子圈—道路集
3对各子图Gi的顶点覆盖子圈—道路集中的子圈和道路进行合并
4在各子图之间进行子圈—道路或子圈—子圈的合并,直到不能合并为止
5若产生了一个圈或一条道路,则输出后结束,否则改变图G的分块方式或分块数后转2继续进行
回复 点赞
whanlx 2004年12月21日
我只得到一组值,肯能有错误,你试试吧
#include "stdafx.h"
#include <afxtempl.h>
#include <fstream>
using namespace std;
#define UNATATACH 0
#define ATATACH 1
CList<CPoint ,CPoint> Stack;
void FindPath(int ChessBoard[][9],int row,int col);
int CheckPos(int ChessBoard[][9],int row,int col)
{
if(0<=row&&row<10&&0<=col&&col<9&&ChessBoard[row][col]==UNATATACH)
{
if(Stack.GetCount()==88) return 1;
else return 0;
}
else return -1;
}
void Save()
{
fstream OutFile;
OutFile.open("c:\\aaa.txt",ios::ate|ios::out|ios::trunc);
POSITION pos = Stack.GetHeadPosition();
while(pos)
{
CPoint p = Stack.GetNext(pos);
char s[100];
sprintf(s,"%d,%d\r\n",p.x,p.y);
OutFile.write(s,strlen(s));
}

OutFile.close();

}
void TryPath(int ChessBoard[][9],int row,int col,int Iflast)
{
int ret = CheckPos(ChessBoard,row,col);
if(ret==1)
{
Save();
ChessBoard[row][col]=0;
}
if(ret==0)
{
Stack.AddTail(CPoint(row,col));
ChessBoard[row][col]=1;
FindPath(ChessBoard,row,col);
}
if(ret==-1)
{
if(Iflast==1)
{
if(Stack.IsEmpty()) Stack.RemoveTail();
}
}

}
void FindPath(int ChessBoard[][9],int row,int col)
{
TryPath(ChessBoard,row+1,col+2,0);
TryPath(ChessBoard,row+1,col-2,0);
TryPath(ChessBoard,row-1,col+2,0);
TryPath(ChessBoard,row-1,col-2,0);
TryPath(ChessBoard,row+2,col+1,0);
TryPath(ChessBoard,row+2,col-1,0);
TryPath(ChessBoard,row-2,col+1,0);
TryPath(ChessBoard,row-2,col-1,1);

}
int Horse(int row,int col)
{
if(0<=row&&row<10&&0<=col&&col<9)
{
int ChessBoard[10][9]={{0}};
ChessBoard[row][col]=1;
FindPath(ChessBoard,row,col);
return 0;
}
else return -1;
}
回复 点赞
Bread_0053 2004年12月21日
呵呵,今天正好学到这里,理论上这是一个np完全问题,穷举的话,一般的巨型机要算10^27年。。。。可以算出一个部分解,等我写一下,大约晚上贴出来给大家看看
回复 点赞
Michael_555 2004年12月21日
上面的MAX定义成了8。
下面的代码是一个在5*5的棋盘上的跳马问题。只输出了所走过的各位置的坐标。


#include "stdio.h"
#define MAX 5

int a[MAX][MAX];
int b[MAX*MAX],c[MAX*MAX];
int scheme;

//显示符合规则的跳马方案
void print(void)
{
int i;

for(i=0;i<MAX*MAX-1;i++)
printf("(%d,%d)\t",c[i],b[i]);
//统计方案总数
++scheme;

printf("\n");
}

//跳马函数,通过递归调用,寻找下一步的位置
int horse(int x,int y,int step)
{
int i,j;

//标识棋子在棋盘中的当前位置已跳过
a[x][y]=1;
//记录棋子在棋盘中的当前位置
b[step]=x;
c[step]=y;
//判断是否找到符合规则的完整的跳马方案(跳马步数为24步时)
if(step>=MAX*MAX-1)
print(); //打印完整的跳马路径

//寻找下一步位置,共有八种可选位置,逐一迳行试探,
//如果符合要求(此位置不越界,在棋盘内,且此点未被跳过),
//则继续递归调用寻找此位置的下一位置,如此点不符合要求,
//则返回0,递归回退。
if((i=x+1)>=0 && (i=x+1)<MAX && (j=y+2)>=0 && (j=y+2)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x+2)>=0 && (i=x+2)<MAX && (j=y+1)>=0 && (j=y+1)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x+2)>=0 && (i=x+2)<MAX && (j=y-1)>=0 && (j=y-1)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x+1)>=0 && (i=x+1)<MAX && (j=y-2)>=0 && (j=y-2)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x-1)>=0 && (i=x-1)<MAX && (j=y+2)>=0 && (j=y+2)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x-2)>=0 && (i=x-2)<MAX && (j=y+1)>=0 && (j=y+1)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x-2)>=0 && (i=x-2)<MAX && (j=y-1)>=0 && (j=y-1)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x-1)>=0 && (i=x-1)<MAX && (j=y-2)>=0 && (j=y-2)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

//对没找到合适位置的处理
//至当前位置状态为0,恢复未跳过状态
a[x][y]=0;

//清除设置记录跳过位置的坐标
b[step]=c[step]=-1;

return 0;
}
int main(int argc, char* argv[])
{

int i,j;
//初始化棋盘位置
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
a[i][j] = 0;

//初始化记录坐标数组
for(i=0;i<MAX;i++)
b[i] = c[i] = -1;

//寻找符合要求的方案
horse(0,0,0);
printf("There are %d schemes\n",scheme);
return 1;
}

回复 点赞
Michael_555 2004年12月21日
下面的代码是一个在5*5的棋盘上的跳马问题。只输出了所走过的各位置的坐标。


#include "stdio.h"
#define MAX 8

int a[MAX][MAX];
int b[MAX*MAX],c[MAX*MAX];
int scheme;

//显示符合规则的跳马方案
void print(void)
{
int i;

for(i=0;i<MAX*MAX-1;i++)
printf("(%d,%d)\t",c[i],b[i]);
//统计方案总数
++scheme;

printf("\n");
}

//跳马函数,通过递归调用,寻找下一步的位置
int horse(int x,int y,int step)
{
int i,j;

//标识棋子在棋盘中的当前位置已跳过
a[x][y]=1;
//记录棋子在棋盘中的当前位置
b[step]=x;
c[step]=y;
//判断是否找到符合规则的完整的跳马方案(跳马步数为24步时)
if(step>=MAX*MAX-1)
print(); //打印完整的跳马路径

//寻找下一步位置,共有八种可选位置,逐一迳行试探,
//如果符合要求(此位置不越界,在棋盘内,且此点未被跳过),
//则继续递归调用寻找此位置的下一位置,如此点不符合要求,
//则返回0,递归回退。
if((i=x+1)>=0 && (i=x+1)<MAX && (j=y+2)>=0 && (j=y+2)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x+2)>=0 && (i=x+2)<MAX && (j=y+1)>=0 && (j=y+1)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x+2)>=0 && (i=x+2)<MAX && (j=y-1)>=0 && (j=y-1)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x+1)>=0 && (i=x+1)<MAX && (j=y-2)>=0 && (j=y-2)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x-1)>=0 && (i=x-1)<MAX && (j=y+2)>=0 && (j=y+2)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x-2)>=0 && (i=x-2)<MAX && (j=y+1)>=0 && (j=y+1)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x-2)>=0 && (i=x-2)<MAX && (j=y-1)>=0 && (j=y-1)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

if((i=x-1)>=0 && (i=x-1)<MAX && (j=y-2)>=0 && (j=y-2)<MAX && !a[i][j])
if(horse(i,j,step+1))
return 1;

//对没找到合适位置的处理
//至当前位置状态为0,恢复未跳过状态
a[x][y]=0;

//清除设置记录跳过位置的坐标
b[step]=c[step]=-1;

return 0;
}
int main(int argc, char* argv[])
{

int i,j;
//初始化棋盘位置
for(i=0;i<MAX;i++)
for(j=0;j<MAX;j++)
a[i][j] = 0;

//初始化记录坐标数组
for(i=0;i<MAX;i++)
b[i] = c[i] = -1;

//寻找符合要求的方案
horse(0,0,0);
printf("There are %d schemes\n",scheme);
return 1;
}
回复 点赞
ewayne 2004年12月21日
递归,回溯!
回复 点赞
xinde 2004年12月21日
呵呵,有挑战性啊.
回复 点赞
autoegg 2004年12月21日
楼主需要大家怎么帮助你呢?给思路?给设计?给代码?
回复 点赞
发动态
发帖子
C++ 语言
创建于2007-09-28

3.1w+

社区成员

24.8w+

社区内容

C++ 语言相关问题讨论,技术干货分享
社区公告
暂无公告