关于递归的跳马问题。

dccrazyboy 2009-04-25 10:55:22
题目如下:在5*5格的棋盘上,有一个中国象棋的马,它可以朝8个方向跳,但不允许出界或跳到已跳过的格子上,要求不重复的跳过所有位置。(最后不要求回到起点)
这是我写的代码,但有问题,在第一次递归时就提示错误:unhandled exception in cpp1.exe 0xC0000FD:Stack Overflow.

#include<iostream>
using namespace std;
#define size 5
int num=0; //用来统计一共有多少种;
void put(bool chess[size][size],int x,int y);
bool finish(bool chess[size][size]);
//bool chess[size][size] true表示已经走过了,false表示没有走过。
int main()
{ bool chess[size][size];
//初始化表格;
int i,j;
for (i = 0 ; i < size ; i++)
for (j = 0 ; j< size ; j++)
chess[i][j]=false;
//放置;
put(chess,0,0);
cout << num;
system("pause");
}

void put(bool chess[size][size],int x,int y)
{ int i,j;
chess[x][y]=true;
if ( !finish(chess) ) //没有结束;
for (i = 0 ; i < size ; i++)
for (j = 0 ; j< size ; j++)
{ if ( (x-i)*(x-i) + (y-j)*(y-j) == 5 ) //满足两点距离的平方为5,所以可以走;
put(chess,i,j);
}
else
num++;
}

bool finish(bool chess[size][size])
{ int i,j;
for (i = 0 ; i < size ; i++)
for (j = 0 ; j< size ; j++)
if ( chess[i][j] != true ) return false;
return true;
}


请问下是怎么回事?
...全文
636 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
dccrazyboy 2009-04-26
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 zhh157 的回复:]
在楼主的代码上稍微改了一下
注释我就不多写了
楼主好好体会吧

C/C++ code
#include <iostream>
#include <string>

using namespace std;

#define size 5

int num=0; //用来统计一共有多少种;
void put(bool chess[size][size],int x,int y);
bool finish(bool chess[size][size]);
//bool chess[size][size] true表示已经走过了,false表示没有走过。

void put(bool chess[size][size],int x,int y…
[/Quote]

答案是308种,这个算出来好像不对啊?
dccrazyboy 2009-04-25
  • 打赏
  • 举报
回复
哦,谢谢,我先试试。
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 dccrazyboy 的回复:]
引用 4 楼 hairetz 的回复:
关键是你这个算法只有递归,没有回溯,你没有发现每次走完,都是置的chess[x][y]=true;
根本没有针对if(chess[x][y]==false)的回溯判断,所以在finish(chess)满足钱是无限递归。

而且统计的num肯定只是1,因为你没有回溯。


哦,能否修改下,或者给我说下怎样修改呢?
[/Quote]

添加对if(chess[x][y]==false)的判断,并进行回溯。
由于你需要判断遍历整个棋盘,所以每次递归最好生成一个棋盘副本。大体这样吧
wanghao111 2009-04-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 hairetz 的回复:]
{ if ( (x-i)*(x-i) + (y-j)*(y-j) == 5 ) //满足两点距离的平方为5,所以可以走;
put(chess,i,j);
}


没必要这要作为马字测法吧。

一般是写一个位移的二维数组
move[8][2]={{2,1},{2,-1},......}

然后你的算法太简单了,递归过多,导致栈不够用。
[/Quote]
dccrazyboy 2009-04-25
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hairetz 的回复:]
关键是你这个算法只有递归,没有回溯,你没有发现每次走完,都是置的chess[x][y]=true;
根本没有针对if(chess[x][y]==false)的回溯判断,所以在finish(chess)满足钱是无限递归。

而且统计的num肯定只是1,因为你没有回溯。
[/Quote]

哦,能否修改下,或者给我说下怎样修改呢?
  • 打赏
  • 举报
回复
关键是你这个算法只有递归,没有回溯,你没有发现每次走完,都是置的chess[x][y]=true;
根本没有针对if(chess[x][y]==false)的回溯判断,所以在finish(chess)满足钱是无限递归。

而且统计的num肯定只是1,因为你没有回溯。
dccrazyboy 2009-04-25
  • 打赏
  • 举报
回复
哦 ,我了解二维数组的算法,但觉得这么些比较简单,请问有没有方法解决?
  • 打赏
  • 举报
回复
{ if ( (x-i)*(x-i) + (y-j)*(y-j) == 5 ) //满足两点距离的平方为5,所以可以走;
put(chess,i,j);
}


没必要这要作为马字测法吧。

一般是写一个位移的二维数组
move[8][2]={{2,1},{2,-1},......}

然后你的算法太简单了,递归过多,导致栈不够用。
liliangbao 2009-04-25
  • 打赏
  • 举报
回复
帮顶~
liubuweiright 2009-04-25
  • 打赏
  • 举报
回复
学习...

S_zxing 2009-04-25
  • 打赏
  • 举报
回复
帮顶……
old-six-programmer 2009-04-25
  • 打赏
  • 举报
回复
在楼主的代码上稍微改了一下
注释我就不多写了
楼主好好体会吧

#include <iostream>
#include <string>

using namespace std;

#define size 5

int num=0; //用来统计一共有多少种;
void put(bool chess[size][size],int x,int y);
bool finish(bool chess[size][size]);
//bool chess[size][size] true表示已经走过了,false表示没有走过。

void put(bool chess[size][size],int x,int y)
{
if( finish( chess ) )
return;
else
{
int nX, nY, nDistance;
//寻找下一点
for( int i = 0; i < size * size; ++i )
{
nX = i%size;
nY = i/size;
nDistance = (x-nX)*(x-nX) + (y-nY)*(y-nY);
if ( nDistance > 0 && nDistance <=2 && !chess[nX][nY] ) //满足两点距离小于等于2
//且不能为自身
{
chess[nX][nY] = true;
put(chess,nX,nY);
break;
}
}
num++;
}
}

bool finish(bool chess[size][size])
{
int i,j;
for (i = 0 ; i < size ; i++)
for (j = 0 ; j< size ; j++)
if ( chess[i][j] != true ) return false;
return true;
}

int main(int argc, char *argv[])
{
bool chess[size][size];
//初始化表格;
int i,j;
for (i = 0 ; i < size ; i++)
for (j = 0 ; j< size ; j++)
chess[i][j]=false;
//放置;
chess[0][0] = true;
put(chess,0,0);
cout<<num<<endl;

for (i = 0 ; i < size ; i++)
{
for (j = 0 ; j< size ; j++)
cout<<chess[i][j]<<" ";
cout<<endl;
}

system("PAUSE");
return EXIT_SUCCESS;
}

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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