在“马的遍历问题”(8*8)中最后怎样使马回到出发点

jiaxiang 2003-12-20 03:16:20
这个算法相信大家都很熟了。
...全文
143 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
anycw 2003-12-26
  • 打赏
  • 举报
回复
用递归
对于任意一个起点找出所有路径
判断最后一步和开始位置是不是只差一步
dukewu 2003-12-26
  • 打赏
  • 举报
回复
teddyzhai(我是猪),
你好,我们数据结构也要做那道题,程序发给我吧:duke-1722@163.com
谢了!
manyroads 2003-12-26
  • 打赏
  • 举报
回复
算法作业要自己想啊。人家已经给你算法思想了,应该是自己用代码实现吧?



小弟不才,斗胆了。
jiaxiang 2003-12-26
  • 打赏
  • 举报
回复
manyroads(流水……小飞侠) :
这个题目我是做了的。只是还不合符要求。所以就提出来了。我的问题相信写的很清楚。
jiaxiang 2003-12-24
  • 打赏
  • 举报
回复
能否都程序进行一个比较详细的说明啊?
yaray 2003-12-24
  • 打赏
  • 举报
回复
快乐!!!
hdqqq 2003-12-24
  • 打赏
  • 举报
回复
计算时间和可能的走法尝试的顺序有关,同时我的程序对尝试的步骤作了一些限制,第一步为0,0的情况下,搜索的空间会小一点,如果初始位置的可能步数越多,搜索的空间越大.
jiaxiang 2003-12-24
  • 打赏
  • 举报
回复
问题仍没有解决,在任意一个起点都有一条路径可以是 *起点与终点重合*
欢迎大家发言!
jiaxiang 2003-12-23
  • 打赏
  • 举报
回复
哎,问题还是没有解决。出发点与终点重合是这个问题的难点。不能回的,我已经做了。
不过还是感谢你!

那个高手帮帮小弟啊!
jiaxiang 2003-12-23
  • 打赏
  • 举报
回复
上面的仁兄,很感谢你提供的代码。我在测试的过程中,起始位置只有(0,0)成功。你能不能解释一下设计的思路、算法的思想?对关键的变量、步骤提供说明,谢谢!
teddyzhai 2003-12-23
  • 打赏
  • 举报
回复
但是我看了一下,我那个好象不能回到出发点呀!!
我还是发给你了。
hdqqq 2003-12-23
  • 打赏
  • 举报
回复
//vc6 and dev-cpp 4.98 tested
#include <iostream>
#include <stack>
using namespace std;

#ifdef _MSC_VER //使用vc编译器
typedef int BOOL;
#endif

struct chess_step{
int stepid;
int stepx;
int stepy;
};

class chess_plan {
private:
int m_axis[8][8]; //用于棋盘
int m_curcal; //当前计算到的步数
chess_step m_first; //第一步的初试值
chess_step m_curstep; //当前的步
int m_firstfree;
stack<chess_step> m_stlstack; //使用stl堆栈
public:
inline chess_plan() : m_curcal(0) {}
inline void initial(int a,int b) {
for(int i=0;i<8;i++) {
for(int j=0;j<8;j++)
m_axis[i][j] = 0;
}
m_curcal = 1;
m_first.stepid = 1;
m_first.stepx = a;
m_first.stepy = b;
m_curstep.stepid = 1;
m_curstep.stepx = a;
m_curstep.stepy = b;
m_axis[a][b] = 1;
}

inline BOOL calover(); //检查是否计算完成
int calfree(int); //计算第一步可能的连接
inline BOOL cantry(int,int);

inline BOOL pushstl(); //压入下一步的可能走法
inline BOOL popstl(); //弹出走法
void calcstep();
void printresult();
};
const int direction[] = {1,2,2,1,2,-1,1,-2,-1,-2,-2,-1,-2,1,-1,2};
BOOL chess_plan::pushstl()
{
int m,n;
chess_step step;
step.stepid = 2000;
for (int i = 0; i < 8; i ++) {
m = m_curstep.stepx + direction[i*2];
n = m_curstep.stepy + direction[i*2+1];
if((m >= 0 && m <= 7) && (n >= 0 && n <= 7) && m_axis[m][n] == 0) {
if(cantry(m,n)){
step.stepid = m_curcal + 1;
step.stepx = m;
step.stepy = n;
m_stlstack.push(step);
}
}
}
if(step.stepid != 2000) { //压到了下一步
m_curcal ++;
m_curstep.stepid = m_curcal;
m_curstep.stepx = step.stepx;
m_curstep.stepy = step.stepy;
m_axis[step.stepx][step.stepy] = m_curcal;
return 1;
}else{ //没有压入下一步
return 0;
}
}

BOOL chess_plan::popstl()
{
chess_step pstep;
chess_step nstep;

pstep = m_stlstack.top();
m_stlstack.pop();
m_axis[pstep.stepx][pstep.stepy] = 0;
nstep = m_stlstack.top();

while(pstep.stepid != nstep.stepid) {
pstep = m_stlstack.top();
m_stlstack.pop();
m_axis[pstep.stepx][pstep.stepy] = 0;
nstep = m_stlstack.top();
}

//memcpy((void*)&m_curstep,nstep,sizeof(chess_step));
m_curstep = nstep;
m_axis[nstep.stepx][nstep.stepy] = nstep.stepid;
m_curcal = nstep.stepid ;
return 0;
}

//计算第一步可能的连接
int chess_plan::calfree(int a)
{
m_firstfree = a;
return m_firstfree;
}

BOOL chess_plan::cantry(int x,int y)
{
if(m_curcal < 63) {
if(abs((x - m_first.stepx) * (y - m_first.stepy)) == 2) {
if(m_firstfree > 1) {
m_firstfree --;
return 1;
}else{
return 0;
}
}
}
return 1;
}

BOOL chess_plan::calover()
{
//return ((m_curcal >= 64) ? 1 : 0);
if(m_curcal >= 64) {
if(abs((m_curstep.stepx - m_first.stepx) * (m_curstep.stepy - m_first.stepy)) == 2)
return 1;
}
return 0;
}

void chess_plan::calcstep()
{
int count = 0;
int i,j;
while(!calover()) {
if(!pushstl()){
popstl();
}
count ++;
if(count > 5000000) {
count = 0;
printresult();
}
}
printresult();
}

void chess_plan::printresult()
{
for(int i=0;i<8;i++) {
for(int j=0;j<8;j++)
printf("%2d ",m_axis[7-i][j]);
printf("\n");
}
printf("%d\n\n",m_curcal);
}

int main(int argc, char* argv[])
{
chess_plan plan;
plan.initial(0,0);
plan.calfree(2);
plan.calcstep();
return 0;
}
jiaxiang 2003-12-23
  • 打赏
  • 举报
回复
很感谢上面的仁兄。你的想法很好。但是还是不能解决出#发点与终点#是一样的问题。我是用回溯法来做的。 但是尝试了很久,还是不能成功---让*马走完整个棋盘,最后一步能够跳回出发点*

我也不知道该该给分¥#~?*

希望各位好手就这个问题再发表意见!谢谢!
redhat_xu 2003-12-23
  • 打赏
  • 举报
回复
因为刚做个这种题目,故贴上来让大家看看,本程序在VC6.0上运行成功!
在程序中,为了尽快地的得到解。我们在程序中做了改进。每次搜索的时候都从可以搜索的方向中选取走法数最少的位置作为我们下一步位置。实际上,这是非常有必要的。因为若每一个位置都搜索其可能走的所有方向,这对于计算机来说将是一个巨大的任务,很有可能得不到结果。我所用的算法是改进了的穷举法。
该算法的设计思想主要大致如下:
for 对棋盘上的每一个位置(由(sx,sy)表示)
{开始从方向0 走 start=0
do { 初始化board[8][8] (全置0)
i=sx;sy=j;
for(step=2;step<=64;step++)
{ 计算下一位置,并将它赋给i,j
若下一位置不存在 跳出
否则 走到下一位置
记录board[i][j]=step
}
若得到一种解,则输出
start++ /*从下一个方向开始重新搜索*/
}while(start〈=8&&step<64〉
}


#include<iostream.h>
#include<stdio.h>
#include<conio.h>
int deltai[]={2,1,-1,-2,-2,-1,1,2};
int deltaj[]={1,2,2,1,-1,-2,-2,-1};
int board[8][8];
int num=1;
//计算在坐标(i,j)的马的出口数,s表示从第几个方向开始
//其中数组a保存的是出口信息(下一个可走的方向)
int exitn(int i,int j,int s,int a[])
{ int i1,j1,k,count;
for(count=k=0;k<8;k++)
{ i1=i+deltai[(s+k)%8];
j1=j+deltaj[(s+k)%8];
if(i1>=0&&i1<8 && j1>=0 && j1<8 && board[i1][j1]==0)
a[count++]=(s+k)%8;
}
return count;
}
/*选择出口数最少的出口,s为顺序选择的开始序号*/
//其返回值是下一个方向的下标,下一个方向走不通则返回-1
int next(int i,int j,int s)
{ int m,k,kk,min,a[8],b[8],temp;
m=exitn(i,j,s,a);
if(m==0) return -1;
for(min=9,k=0;k<m;k++)
{ temp=exitn(i+deltai[a[k]],j+deltaj[a[k]],s,b);
if(temp<min) { min=temp; kk=a[k]; }
}
return kk;
}

void main()
{ int sx,sy,i,j,step,no,start;
cout<<"========== 马的遍历问题 ==========="<<endl;
cout<<"数值代表该格子是第几步走到的"<<endl;
cout<<"按任意键可查看从下一个位置的走法"<<endl<<endl;
for(sx=0;sx<8;sx++)
for(sy=0;sy<8;sy++)
{ start=0;
do
{ for(i=0;i<8;i++)
for(j=0;j<8;j++)
board[i][j]=0;
board[sx][sy]=1;
i=sx;j=sy;
for(step=2;step<=64;step++)
{ if((no=next(i,j,start))==-1) break;
i+=deltai[no]; j+=deltaj[no]; board[i][j]=step;
}
if(step>64)
{ cout<<"第"<<num<<"种走法为:"<<endl;
for(i=0;i<8;i++)
{ for(j=0;j<8;j++)
cout<<"--"<<board[i][j];
cout<<"--"<<endl;
}
num++;
}
start++;
}while(start<8&&step<=64);
}
cout<<"所得到的结果为"<<--num;
getche();
}
不知这样有没有分呀!
mickyx 2003-12-23
  • 打赏
  • 举报
回复
我仅知道出发点要选择一下,有的点是不能回的
MotoBULL 2003-12-22
  • 打赏
  • 举报
回复
如果要找到所有的解广度优先和深度优先是一样的!
下面是我的源程序:
#include <stdio.h>
#include <math.h>
int a[8][8];
void initialize(int b[][8])
{
int i,j;
for (i=0;i<8;i++)
for (j=0;j<8;j++)
b[i][j]=0;
}
bool unhopout(int x,int y)
{
if ((x>=0)&&(x<=7)&&(y>=0)&&(y<=7))
{
//printf("true");
return true;
}
else
return false;
}
void findout(int recordx[],int recordy[])
{
int i;
printf("find out a path:\n");
for (i=0;i<64;i++)
printf("%d %d;",recordx[i],recordy[i]);
printf("\n");


}
void hop(int b[][8],int x,int y,int start_x,int start_y,int *num,int recordx[],int recordy[],int *sum)
{
//printf("%d ",*num);
int c[4]={-2,-1,1,2},d[2]={-1,1};
int next_x,next_y,i,j;
for (i=0;i<4;i++)
for (j=0;j<2;j++)
{
// printf("%d %d;",recordx[*num-1],recordy[*num-1]);
next_x=x+c[i];
next_y=y+d[j]*(3-abs(c[i]));
if (unhopout(next_x,next_y))
{
// printf("%d %d %d %d ",next_x,start_x,next_y,start_y);
// printf("%d",((next_x==start_x)&&(next_y==start_y)&&(*num==64)));
if ((next_x==start_x)&&(next_y==start_y)&&(*num==64))
{
//printf("%d",i);
findout(recordx,recordy);
*sum=*sum+1;
printf("%d",*sum);


}
else
if (b[next_x][next_y]!=1)
{

*num=*num+1;
recordx[*num-1]=next_x;
recordy[*num-1]=next_y;
b[next_x][next_y]=1;
//printf("%d ",*num);
hop(b,next_x,next_y,start_x,start_y,num,recordx,recordy,sum);
}
}

}
*num=*num-1;
b[x][y]=0;



}

void main()
{
int b[8][8],recordx[64],recordy[64];
initialize(b);
int start_x,start_y,count=1,sum=1;
printf("please put in the position which the horse start:");
scanf("%d%d",&start_x,&start_y);
b[start_x][start_y]=1;
recordx[0]=start_x;
recordy[0]=start_y;
//printf("%d ",count);
hop(b,start_x,start_y,start_x,start_y,&count,recordx,recordy,&sum);
}
jiaxiang 2003-12-22
  • 打赏
  • 举报
回复
上面的师兄很感谢你提供的代码,但是我在我的机上不能通过,不知是什么原因?
调试时出现的信息是:
Loaded 'ntdll.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\kernel32.dll', no matching symbolic information found.
Loaded 'C:\Program Files\rising\rav\ApiHook.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\advapi32.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\rpcrt4.dll', no matching symbolic information found.
Loaded 'C:\Program Files\rising\rav\Memmon.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\user32.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\gdi32.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\imm32.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\lpk.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\usp10.dll', no matching symbolic information found.
The thread 0x38C has exited with code -1073741510 (0xC000013A).
The thread 0xE10 has exited with code -1073741510 (0xC000013A).
The thread 0x930 has exited with code -1073741510 (0xC000013A).
The program 'C:\Documents and Settings\ljf\桌面\新建文件夹\Debug\2.exe' has exited with code -1073741510 (0xC000013A).



teddyzhai,你好。我的油箱地址是 ljf@hotmail.com 等你的回信
teddyzhai 2003-12-22
  • 打赏
  • 举报
回复
哈哈,还是重庆8中的网站呢
teddyzhai 2003-12-22
  • 打赏
  • 举报
回复
我有源码,要吗
我们数据结构才做了此题,留油箱
wongsung 2003-12-21
  • 打赏
  • 举报
回复
回溯法
加载更多回复(6)

1,978

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 其他语言讨论
社区管理员
  • 其他语言社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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