马的遍历——搜索与回溯
题目描述 Description
中国象棋半张棋盘如图所示。马自左下角往右上角跳。今规定只许往右跳,不许往左跳。比如图4(a)中所示为一种跳行路线,并将所经路线打印出来。
输入输出格式 Input/output
输入格式:
无
输出格式:
无
输出格式:
第一行:一个整数total表示第几种跳法
第二行:0,0-->2,1-->3,3-->1,4-->3,5-->2,7-->4,8
输入输出样例 Sample input/output
样例测试点#1
输入样例:
无
输出样例:
1
0,0-->2,1-->3,3-->1,4-->3,5-->2,7-->4,8…
【算法分析】
如图4(b),马最多有四个方向,若原来的横坐标为j、纵坐标为i,则四个方向的移动可表示为:
1: (i,j)→(i+2,j+1); (i<3,j<8)
2: (i,j)→(i+1,j+2); (i<4,j<7)
3: (i,j)→(i-1,j+2); (i>0,j<7)
4: (i,j)→(i-2,j+1); (i>1,j<8)
搜索策略:
S1:A[1]:=(0,0);
S2:从A[1]出发,按移动规则依次选定某个方向,如果达到的是(4,8)则转向S3,否则继续搜索下一个到达的顶点;
S3:打印路径。
思路:可以用一个数组存路径,循环四次(四种移动规则)
判断条件是否成立(是否在格子内)
成立,保存当前马的位置,再判断是否跳到头了,是就输出(传入输出函数),反之则继续寻找
代码如下:
1 #include <stdio.h> 2 int a[100][100],total=0;//路径总数和路径 3 int x[4]={2,1,-1,-2},y[4]={1,2,2,1};//四种移动规则 4 int print(int ii) 5 { 6 int i; 7 total++; 8 printf("%d\n",total); 9 for(i=0;i<ii;i++) 10 { 11 printf("%d,%d-->",a[i][1],a[i][2]); 12 } 13 printf("4,8\n"); 14 } 15 int search(int i) 16 { 17 int j; 18 for(j=0;j<=3;j++) 19 { 20 if(a[i-1][1]+x[j]>=0&&a[i-1][1]+x[j]<=4&&a[i-1][2]+y[j]>=0&&a[i-1][2]+y[j]<=8) //判断马是否越界 21 { 22 a[i][1]=a[i-1][1]+x[j];//保存当前马的位置 23 a[i][2]=a[i-1][2]+y[j];//保存当前马的位置 24 if(a[i][1]==4&&a[i][2]==8) print(i);//到头了,输出 25 else search(i+1);//否则,下一步 26 } 27 } 28 } 29 int main() 30 { 31 a[1][1]=0; 32 a[1][2]=0; 33 search(2); 34 return 0; 35 }
我不怕千万人阻挡,只怕自己投降…