马的遍历问题-回溯法应用-ACM

马的遍历问题

 nm的棋盘中,马只能走“日” 字。马从位置(x,y)处出发,把棋盘的每一格都走一次,且只走一次。找出所有路径。

 

 

问题解的搜索空间?

棋盘的规模是n*m,是指行有n条边,列有m条边。

马在棋盘的点上走,所以搜索空间是整个棋盘上的n*m个点。

n*m的二维数组记录马行走的过程,初值为0表示未经过。

马的遍历问题-回溯法应用-ACM

在寻找路径过程中,活结点的扩展规则?

对于棋盘上任意一点A(x,y),有八个扩展方向:

 

A(x+1,y+2),A(x+2,y+1)

A(x+2,y-1),A(x+1,y-2)

A(x-1,y-2),A(x-2,y-1)

A(x-2,y+1),A(x-1,y+2)

为构造循环体,用数组fx[8]={1,2,2,1,-1,-2,-2,-1},fy[8]= {2,1,-1,-2,-2,-1,1,2}来模拟马走“日”时下标的变化过程。
 
扩展的约束条件

不出边界

每个点只经过一次。

棋盘点对应的数组元素初值为0,对走过的棋盘点的值置为所走步数,起点存储“1”,终点存储“n*m”

函数check,检查当前状态是否合理
 
输入
0 0

输出
1  90 82 75 88 83 78 85 89
71 74 2  64 81 76 87 84 79
44 55 72 69 3  63 80 77 86
73 70 45 56 65 68 4  62 59
54 43 66 51 46 57 60 49 5
41 37 53 31 67 50 47 58 61
35 12 42 38 52 30 25 6  48
20 39 36 13 32 23 16 29 26
11 34 21 18 9  14 27 24 7
40 19 10 33 22 17 8  15 28
 
#include <stdio.h>
#include <string.h>
int matrix[10][9];
int  journey = 1;
int step_x[]={1,2,2,1,-1,-2,-2,-1},step_y[]={2,1,-1,-2,-2,-1,1,2};

void outMatrix(){
	int i,j;
	for (i=0;i<10;i++)
	{
		for (j=0;j<9;j++)
		{
			printf("%-2d ",matrix[i][j]);
		}
		printf("\n");
	}
}

bool outofbounds(int x,int y){
	return x < 0 || y < 0 || x >= 10 || y >= 9;
}

bool isCome(int x,int y){
	return matrix[x][y];
}

void gotoend(int x, int y ){
	if(journey>90) return;
	int i;
	matrix[x][y]=journey++;			//当前是第几步
	for (i = 0;i<8;i++) 
	{
		int next_x = x+step_x[i];
		int next_y = y+step_y[i];
		if(!outofbounds(next_x,next_y) && !matrix[next_x][next_y]){
	
			gotoend(next_x,next_y);
		}
	}
}

int main(){
	int start_x,start_y;
	int i;
	scanf("%d%d",&start_x,&start_y);
	for (i = 0;i<10;i++) {
		memset(matrix[i],0,sizeof(matrix[0]));
	}
	gotoend(start_x,start_y);
	outMatrix();
	return 0;
}


 

上一篇:MonoRail学习笔记十九:可重复使用组件ViewComponents的使用


下一篇:CDN有什么用?我的网站到底需不需要CDN加速?