在线等待,这是一个电脑报上的一个题目,有一个8X8方格矩阵,从开始起点(第一行,第一列)开始按象棋里马的行走规则走不能重复,问走完

xingxing78 2005-03-02 01:09:36
在线等待,这是一个电脑报上的一个题目,有一个8X8方格矩阵,从开始起点(第一行,第一列)开始按象棋里马的行走规则走不能重复,问走完的所有可能的点,最后的点在第几行第几列?谢谢!
...全文
526 24 打赏 收藏 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
tianhxk 2005-04-05
  • 打赏
  • 举报
回复
我的算法复杂度很高,并且是递归算法很容易堆栈溢出,其实可以采用人工智能算法中的启发式搜索,不过忘掉怎么写的了,说实话从一开始学就没有写好过。
tianhxk 2005-04-05
  • 打赏
  • 举报
回复
呵呵,不好意思,没注意到,毕竟这是穷举所有的情况,你自己可以想一下它的解得空间是多少(我估算应该有80!)
vvkl 2005-04-05
  • 打赏
  • 举报
回复
我运行了一下上面那个程序,发现有问题
上面那个源程序的horse函数应该改一下
bool horse(int x,int y,int n)
{
int i;
if(n==(ROW+1)*(COLUMN+1)-1) //这里要改
//原作者说:"你的棋盘是8*8的,对于马来说有9行9列的交叉点可以走。"
//那么n最后应该==9*9-1,而不是8*8-1了
{
cout<<"最后的点落在"<<x<<"行"<<y<<"列"<<endl;
return true ;
}
a[x][y]=1;
for(i=0;i<8;i++)
{
if((x+b[i][0])<=ROW&&(x+b[i][0])>=0&&(y+b[i][1])<=COLUMN&&(y+b[i][1])>=0)
if(!a[x+b[i][0]][y+b[i][1]])
if(horse(x+b[i][0],y+b[i][1],n+1))
{
cout<<"("<<x<<","<<y<<")"<<endl;
return true;
}
}
a[x][y]=0;//这里要加这一句,否则总是无解
return false;
}
还有这个算法比较慢,拿来算4*4,4*5的都没问题,算8*8的就没响应了
javence 2005-03-15
  • 打赏
  • 举报
回复
试探+回溯

试探即以棋子所在位置开始,有n中走法,选取(n中走法中挑选)一走法,并且按此走法后,能挑选的走法最多的为准。

高程考试的书上有例子!
zixiu2008 2005-03-02
  • 打赏
  • 举报
回复
电脑报的题目越来越不景气了……
Mark-阿桂 2005-03-02
  • 打赏
  • 举报
回复
这个题我做过,有很多走法的,最后落到什么地方就不记得了,回朔方法占用时间比较多,其实递归是最好的方法。这个问题可以转化成树的遍历。当时我做的是任意给起始位置,寻找遍历的所有路径。

这里给出算法:

先按8*8的说,当开始的时候,每个方格按照象棋中马走的跳法是固定的了,比如最左上角[0][0]只有2种跳法,只能跳[1][2]和[2][1],我这里定义成度,其实就是树的节点。中间位置[4][4],就可以有8种跳法,度就是8。明白这个之后,只要开始点定下来,这个点度就是0,和它相关的点的度都要减1,因为相关的点就不能在跳到这个点来(不重复的前提),然后寻找相关点中度最小的跳(度是零的不跳),重复上面过程,就可以完成一次寻找。

好长时间了,源程序早不见了(当时用vb写的)。

这个算法是比较简单的了,如果谁还有更好的方法,大家交流一下!
tianhxk 2005-03-02
  • 打赏
  • 举报
回复
给分
ekschencn 2005-03-02
  • 打赏
  • 举报
回复
std是C++的名字空间.对于C++的标准库,都是包含在名字空间std里面的.为了让这些库里面的函数对外可见,需要用using关键字. using namespace std; 是using关键字的一种写法.
sanhill 2005-03-02
  • 打赏
  • 举报
回复
这个程序很好写的!
自己琢磨一下,可以很好的理解这个算法!
tianhxk 2005-03-02
  • 打赏
  • 举报
回复
所有可能的情况为
最后的点落在3行0列
最后的点落在2行7列
最后的点落在2行3列
最后的点落在1行6列
最后的点落在1行6列
最后的点落在0行7列
最后的点落在1行6列
最后的点落在3行0列
tianhxk 2005-03-02
  • 打赏
  • 举报
回复
这是C++的特点,它的意思就是包括名字空间std,std我也说不上来是什么,反正就是这么写的,你也可以不用,但必须得把#include <iostream>改成#include <iostream.h>,#include <memory.h>
tianhxk 2005-03-02
  • 打赏
  • 举报
回复
我的理解是这样的,你的棋盘是8*8的,对于马来说有9行9列的交叉点可以走。
以下是原程序:上一个是4*4的
我把所有的步骤都列出来了,这只是一种情况,还有很多种情况
#include <iostream>
#include <memory>
using namespace std;
#define ROW 8
#define COLUMN 8
int a[ROW+1][COLUMN+1];
int b[8][2]={
{1,2},
{1,-2},
{-1,2},
{-1,-2},
{2,1},
{2,-1},
{-2,1},
{-2,-1}
};
bool horse(int x,int y,int n)
{
int i;
if(n==ROW*COLUMN-1)
{
cout<<"最后的点落在"<<x<<"行"<<y<<"列"<<endl;
return true ;
}
a[x][y]=1;
for(i=0;i<8;i++)
{
if((x+b[i][0])<=ROW&&(x+b[i][0])>=0&&(y+b[i][1])<=COLUMN&&(y+b[i][1])>=0)
if(!a[x+b[i][0]][y+b[i][1]])
if(horse(x+b[i][0],y+b[i][1],n+1))
{
cout<<"("<<x<<","<<y<<")"<<endl;
return true;
}
}
return false;

}
int main()
{
int startx,starty,n;
startx=starty=0;
n=0;
memset(a,0,sizeof(a));
if(horse(startx,starty,n))
cout<<"succeed"<<endl;
else
cout<<"false"<<endl;
return 0;
}
xingxing78 2005-03-02
  • 打赏
  • 举报
回复
using namespace std; 这一句是什么意思可以解释一下吗,小弟是个初学者
tianhxk 2005-03-02
  • 打赏
  • 举报
回复
这个应该可以
#include <iostream>
#include <memory>
using namespace std;
#define ROW 4
#define COLUMN 4
int a[ROW+1][COLUMN+1];
int b[8][2]={
{1,2},
{1,-2},
{-1,2},
{-1,-2},
{2,1},
{2,-1},
{-2,1},
{-2,-1}
};
bool horse(int x,int y,int n)
{
int i;
if(n==ROW*COLUMN-1)
{
cout<<"最后的点落在"<<x<<"行"<<y<<"列"<<endl;
return true ;
}
a[x][y]=1;
for(i=0;i<8;i++)
{
if((x+b[i][0])<=ROW&&(x+b[i][0])>=0&&(y+b[i][1])<=COLUMN&&(y+b[i][1])>=0)
if(!a[x+b[i][0]][y+b[i][1]])
if(horse(x+b[i][0],y+b[i][1],n+1))
return true;
}
return false;

}
int main()
{
int startx,starty,n;
startx=starty=0;
n=0;
memset(a,0,sizeof(a));
if(horse(startx,starty,n))
cout<<"succeed"<<endl;
else
cout<<"false"<<endl;
return 0;
}
xingxing78 2005-03-02
  • 打赏
  • 举报
回复
chunguo_online@yahoo.com.cn
thank you
ekschencn 2005-03-02
  • 打赏
  • 举报
回复
原因就像我说的,太长了,而且自己也不是写的很好。要的话留个邮箱好了
xingxing78 2005-03-02
  • 打赏
  • 举报
回复
可以贴出来吗,我想看看
ekschencn 2005-03-02
  • 打赏
  • 举报
回复
我这里有一个以前我学习回溯法的时候写的,也是这个马行走的问题,不过写得太过拙劣了也太长了,不方便贴上来。如果楼主想要的话我可以给你看看,希望对你学习有所帮助。
pcboyxhy 2005-03-02
  • 打赏
  • 举报
回复
回溯大致就是:

往下一个状态转化,
如果无法继续转换,而又没有到达解状态(目标状态),
就将上一个状态转换到他能转换的下一个状态。

举个例子,
你前面有两条路,
你选择往左走,
遇到一个死胡同,
可是你的目的地不是这个死胡同,
所以你就往回走(回溯),
在最近一个拐弯的地方选择和上次不同方向走,
如果这边所有的方向都走过了,还没到,
就往上上个拐弯处走(回溯)
ekschencn 2005-03-02
  • 打赏
  • 举报
回复
回溯法或者楼上说的那个不是三言两语可以说清楚的。楼主要是想弄清楚的话,最好是找本有关数据结构的书看看。
加载更多回复(4)

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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