[求助]如何有效的实现回溯
骑士巡游问题:在n行n列的棋盘上(如n=5),假设一位骑士(按象棋中“马走日”的行走法)从初始坐标位置(x1,y1)出发,要遍访(巡游)棋盘中的每一个位置一次。请编一个程序,为骑士求解巡游“路线图”(或告诉骑士,从某位置出发时,无法遍访整个棋盘 — 问题无解)。
当n=5时,意味着要在5行5列的棋盘的25个“点”处,按骑士行走规则,依次将1至25这25个“棋子”(数码)分别摆放到棋盘上(摆满25个位置则成功,否则失败问题无解)。
例如,当n=5且初始坐标位置定为(1,1) — 即最左上角的那个点时,如下是一种巡游“路线图”。程序执行后的输出结果为:
(x1,y1)? => (1=>5, 1=>5) : 1 1
1 6 15 10 21
14 9 20 5 16
19 2 7 22 11
8 13 24 17 4
25 18 3 12 23
编制主函数,让用户输入作为巡游起点的初始坐标位置(x1,y1)下面是我的程序,但是没实现成功,不知道如何实现回溯。。。
请高手指点迷津!!!谢谢了
#include <iostream.h>
int a[5][5];
void solve(int i,int j,int k,bool& ok)
{
int g,h;
if(k==26)
ok=true;
else
{
if((i+2)>=0&&(j-1)>=0&&(i+2)<5&&(j-1)<5&&a[i+2][j-1]==0)
{
a[i+2][j-1]=k;
g=i+2,h=j-1;
solve(g,h,k+1,ok);
}
else if((i+2)>=0&&(j+1)>=0&&(i+2)<5&&(j+1)<5&&a[i+2][j+1]==0)
{
a[i+2][j+1]=k;
g=i+2,h=j+1;
solve(g,h,k+1,ok);
}
else if((i+1)>=0&&(j+2)>=0&&(i+1)<5&&(j+2)<5&&a[i+1][j+2]==0)
{
a[i+1][j+2]=k;
g=i+1,h=j+2;
solve(g,h,k+1,ok);
}
else if((i-1)>=0&&(j+2)>=0&&(i-1)<5&&(j+2)<5&&a[i-1][j+2]==0)
{
a[i-1][j+2]=k;
g=i-1,h=j+2;
solve(g,h,k+1,ok);
}
else if((i-2)>=0&&(j+1)>=0&&(i-2)<5&&(j+1)<5&&a[i-2][j+1]==0)
{
a[i-2][j+1]=k;
g=i-2,h=j+1;
solve(g,h,k+1,ok);
}
else if((i-2)>=0&&(j-1)>=0&&(i-2)<5&&(j-1)<5&&a[i-2][j-1]==0)
{
a[i-2][j-1]=k;
g=i-2,h=j-1;
solve(g,h,k+1,ok);
}
else if((i-1)>=0&&(j-2)>=0&&(i-1)<5&&(j-2)<5&&a[i-1][j-2]==0)
{
a[i-1][j-2]=k;
g=i-1,h=j-2;
solve(g,h,k+1,ok);
}
else if((i+1)>=0&&(j-2)>=0&&(i+1)<5&&(j-2)<5&&a[i+1][j-2]==0)
{
a[i+1][j-2]=k;
g=i+1,h=j-2;
solve(g,h,k+1,ok);
}
else
ok=false;
}
}
void main()
{
int x,y;
bool ok;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
a[i][j]=0;
cout<<"请选择从哪点骑士开始巡游(即哪个坐标):";
cin>>x;
cin>>y;
a[x-1][y-1]=1;
solve(x-1,y-1,2,ok);
// if(ok)
// {
for(int m=0;m<5;m++)
{
for(int n=0;n<5;n++)
{
cout<<a[m][n]<<" ";
}
cout<<endl;
}
// }
// else
// cout<<"false"<<endl;
}