骑士遍历问题.docx
《骑士遍历问题.docx》由会员分享,可在线阅读,更多相关《骑士遍历问题.docx(16页珍藏版)》请在冰豆网上搜索。
骑士遍历问题
|返回主页|本站地图|站内搜索|联系信箱|
您目前的位置:
首页>自由软件>技术交流>应用编程
蓝森林2006年6月6日10:
18
关于马踏棋盘问题的求教
最近看了马踏棋盘问题,突然比较感兴趣,写了段程序,主要思路是这样的
/*Analyse:
1.initchessboard
2.startfrom(0.0)andtrydirectionfrom0
3.ifcan_go,gonext;ifcan't,tryanotherdirection
4.ifhavetryallthedirection,gobackoldoneandinitthecurrentpoint
5.iftryallthedirectionofstartpoint(0.0),returncan'tfind,otherwiseprintthechessboard*/
突然想深入了解这个问题,对于n*n的棋盘,求共有多少种走法.要求用C来实现,不知道大家有什么想法.谢谢.
关于马踏棋盘问题的求教
本人新手,在此块讨论区人微言轻,本不敢谈什么个人的看法.
但我以前写过类似的程序,
我做的题是8*8,选择任意点为起点马踏完成,记录每一步.
从理论上来说用递归算法是可以的,但是在TC环境下是得不出答案的
因为递归后,一步一步尝试使递归层越陷越深,不知道怎么的就死了
(哪位能告诉我什么原因吗?
)
最后我找到一种方法
就是不论以哪个点为始点,我都向外围靠,走完外圈再走内圈
所以不论哪个点为始点都能走通.
至于N*N还没有尝试过.
问一下你的程序运行了吗?
关于马踏棋盘问题的求教
深度优先的递归遍历适于求解那些简单问题,因为情况复杂之后,递归深度太大,将造成堆栈耗尽。
比较复杂的问题适于采用广度优先的遍历。
如果情况进一步复杂,还可以在广度节点扩展的时候加入启发函数,进行a*遍历。
方法与深度优先差不多,只不过把栈换成队列即可。
关于马踏棋盘问题的求教
本科的数据结构教材里有这个习题,原题是马的遍历:
从任一起点均可无重复遍历棋盘的所有落子点。
算法比较简单,主要考虑遍历策略,因为走下一步最多有八种可能方法,我的遍历策略是择优遍历下一步的下一步所能选择的方法最少的走法,可以想象靠边的点的走法最少,所以遍历路线是从外到内。
我这里有源码,如果楼主需要可以放上来。
关于马踏棋盘问题的求教
谢谢大家帮忙,我也些了个程序,通过限制递归的次数来解决这个问题,在这里我限制的递归次数为100000,我还想知道知道如果求解6*6或者8*8棋盘可能的解的个数,
这是我的程序,写的比较烂,请大家指教
/*要求:
1.依次输出所走过的各位置的坐标。
2.画出棋盘的图形形式,并在其上动态的标注行走过程。
3.程序能方便的移植到其他规格的棋盘上。
*/
/*Analyse:
1.initchessboard
2.startfrom(0.0)andtryfromdirection0
3.ifcan_go,gonext;ifcan't,tryanotherdirection
4.ifhavetryallthedirection,gobackoldoneandinitthecurrentpoint
5.iftryallthedirectionofstartpoint(0.0),returncan'tfind,otherwiseprintthechessboard*/
#include;
#definexSize8
#defineySize8
#defineMAXSTEP100000
intiStep=0;
longallStep=0;
intxRecord=0,yRecord=0;
intchessboard[xSize][ySize][2];//definechessboard;[0]--count,[1]--direction
intinit_chess()//initchessboard
{
inti,j;
for(i=0;i for(j=0;j {
chessboard[i][j][0]=0;//initcount
chessboard[i][j][1]=0;//initdirection
}
}
intprint_chess()//printchessboard
{
inti,j;
for(i=0;i {
for(j=0;j printf("%4d",chessboard[i][j][0]);
printf("\n\n");
}
}
intsearch_x(intcount)//searchxPointbycount
{
inti,j;
for(i=0;i for(j=0;j if(chessboard[i][j][0]==count)
returni;
return0;
}
intsearch_y(intcount)//searchyPointbycount
{
inti,j;
if(count==0)
return0;
for(i=0;i for(j=0;j if(chessboard[i][j][0]==count)
returnj;
return0;
}
intcan_go(intm,intn)//
{
/*findifitoutboardorhavebeengone*/
if((m>;=0&&m;=0&&n return1;//cango
else
return0;//can'tgo
}
intgo_back(inti,intj)
{
intm,n;
//findoldone(m,n)
m=search_x(chessboard[i][j][0]-1);
n=search_y(chessboard[i][j][0]-1);
//(m,n)direction++
++chessboard[m][n][1];
//clear(i,j)
chessboard[i][j][0]=0;
chessboard[i][j][1]=0;
//gofrom(m,n)
//printf("gobacktoi=%d,j=%d,count=%d\n",m,n,chessboard[m][n][0]);
go(m,n);
}
intgo(inti,intj)
{
intlevel=0,count=0;
intm,n;
level=chessboard[i][j][1];
count=chessboard[i][j][0];
if(count==(xSize*ySize)-1)
{
iStep=-1;
return;
}
iStep++;
allStep++;
if(iStep>;MAXSTEP)
{
xRecord=i;
yRecord=j;
iStep=0;
return;
}
switch(level)
{
case0:
m=i-2;
n=j+1;
break;
case1:
m=i-1;
n=j+2;
break;
case2:
m=i+1;
n=j+2;
break;
case3:
m=i+2;
n=j+1;
break;
case4:
m=i+2;
n=j-1;
break;
case5:
m=i+1;
n=j-2;
break;
case6:
m=i-1;
n=j-2;
break;
case7:
m=i-2;
n=j-1;
break;
default:
/*ifcan'tfindnextgotobacktofirst.*/
//if(i==0&&j==0)/*searchallbutcan'tfind*/
//{
// printf("Can'tfindanytrace");
// return;
//}
go_back(i,j);
return;
}
if(can_go(m,n)==1)
{
chessboard[m][n][0]=++count;
//printf("cango.allStep=%d,iStep=%d,i=%d,j=%d,level=%d,count=%d\n",allStep,iStep,i,j,chessboard[i][j][1],chessboard[i][j][0]);
go(m,n);
}
else
{
chessboard[i][j][1]=++level;
//printf("can'tgo.allStep=%diStep=%d,i=%d,j=%d,level=%d,count=%d\n",allStep,iStep,i,j,chessboard[i][j][1],chessboard[i][j][0]);
go(i,j);
}
}
//#defineCLOCKS_PER_SEC1000000
intmain()
{
inti;
clock_ttime;
//printf("time=%d",time);
//Initchessboard
init_chess();
//gofrom(0.0)
//go(0,0);
do
{
go(xRecord,yRecord);
}while(iStep!
=-1);
time=clock();
printf("SearchOK,allStep=%d\n,time=%d\n",allStep,time/CLOCKS_PER_SEC);
//printgotrace
print_chess();
}
关于马踏棋盘问题的求教
如果是5*5的棋盘,结果是多少种啊?
关于马踏棋盘问题的求教
关于马踏棋盘问题的求教
-->
^_^,那就对了。
偶写的是304种,可是在网上搜的一个论坛上的一篇帖子中提到是1000多种。
怕自己错了。
JohnBull都说了,那一定没错了。
超相信JohnBull老大的算法。
关于马踏棋盘问题的求教
-->
OK!
Buddy!
righttogether,wrongtogether!
:
em11:
关于马踏棋盘问题的求教
偶怎么得出来有30000多种?
[code]#include;
struct_steps{
intnextX;
intnextY;
}steps[]={
{-2,-1},
{-2,1},
{-1,-2},
{-1,2},
{1,-2},
{1,2},
{2,-1},
{2,1}
};
intnSize,nSteps,nCount;
intstartx=0,starty=0;
char**Board;
typedefstructstepstack{
intx;
inty;
structstepstack*next;
}step;
step*head=NULL,*tail=NULL;
step**pStep=&head;
intInitBoard()
{
inti,j;
Board=(char**)malloc(nSize*sizeof(char*));
if(Board==NULL)return-1;
for(i=0;i Board[i]=(char*)malloc(nSize);
if(Board[i]==NULL)return-2;
for(j=0;j Board[i][j]=0;
}
return0;
}
voidFindPoint(inta,intb,intx,inty)
{
inti,nextA,nextB,nNum;
step *newstep,*oldstep,*steplist;
nNum=0;
for(i=0;i<8;i++){
nextA=a+steps[i].nextX;
nextB=b+steps[i].nextY;
if(nextA<0||nextA>;=nSize||nextB<0||nextB>;=nSize)continue;
if(Board[nextA][nextB]==1)continue;
oldstep=tail;
newstep=(step*)malloc(sizeof(step));
newstep->;x=a;
newstep->;y=b;
newstep->;next=NULL;
tail=newstep;
*pStep=newstep;
pStep=&(newstep->;next);
Board[a][b]=1;
nSteps++;
if(nextA==x&&nextB==y){
printf("STEPS[%d]:
",nSteps);
for(steplist=head;steplist!
=NULL;steplist=steplist->;next){
printf("(%d,%d)==>;", steplist->;x,steplist->;y);
}
printf("(%d,%d)\n",x,y);
nCount++;
}
else
FindPoint(nextA,nextB,x,y);
Board[a][b]=0;
nSteps--;
free(newstep);
if(oldstep!
=NULL){
oldstep->;next=NULL;
pStep=&(oldstep->;next);
tail=oldstep;
}
else{
head=NULL;
pStep=&head;
tail=NULL;
}
}
return;
}
main()
{
inti,x,y;
printf("Inputthechessboardsize:
");
scanf("%d",&nSize);
if(InitBoard()<0){
printf("memoryerror.\n");
exit(-1);
}
do{
printf("Inputthetargetposition(x,y):
");
scanf("%d,%d",&x,&y);
}while(x<0||x>;=nSize||y<0||y>;=nSize);
nSteps=0;
nCount=0;
FindPoint(startx,starty,x,y);
printf("COUNT:
%d\n",nCount);
}
[/code]
关于马踏棋盘问题的求教
关于马踏棋盘问题的求教
一个位置当然只能走一次,不然有无穷多种可能了
为什么吃了我好多字?
关于马踏棋盘问题的求教
yuxh注释一下吧,嘿嘿,又有东西学了。
关于马踏棋盘问题的求教
这是偶的代码:
[code]
#include;
#include;
#include;
#include;
#defineN 5 //howbigisthechessboard?
int status[N][N]; //thepointstatus.
int ok[N][N]; //toimprovetheeffciency.
int step[N*N][2]; //storethesteps.
int count=0; //counttheresults.
staticvoidhorse_go(intx,inty); //recursetofindtheresults.
staticvoidmove(intx,inty,int*px1,int*py1,inti); //