Uva439骑士移动(图和图的遍历-BFS)

题目:

A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visits each square of a given set of n squares on a chessboard exactly once. He thinks that the most difficult part of the problem is determining the smallest number of knight moves between two given squares and that, once you have accomplished this, finding the tour would be easy.

Of course you know that it is vice versa. So you offer him to write a program that solves the ”difficult” part.

Your job is to write a program that takes two squares a and b as input and then determines the number of knight moves on a shortest route from a to b.

Input

The input file will contain one or more test cases. Each test case consists of one line containing two squares separated by one space. A square is a string consisting of a letter (a..h) representing the column and a digit (1..8) representing the row on the chessboard.

Output

For each test case, print one line saying ‘To get from xx to yy takes n knight moves.’.

思路:

国际象棋棋盘(下图)与骑士走法:每步棋先横走或直走一格,然后再斜走一格;或者先斜走一格,最后再横走或竖走一格。可以越子,没有"中国象棋"中"蹩马腿"的限制。也是走“日”字格,是三乘二的“日”字格。

https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1532090663&di=2a144d3b994b44541ec45af38aee7621&src=http://img.juimg.com/tuku/yulantu/140702/330752-140F216152835.jpg

(棋盘范围内)遍历所有邻接点记步数+1,如果没到则再扩大一层并,直到到达目的地

传递/记录步数

标记已经走过

处理死路

Debug: invalid types 'int[int]' for array subscript——数组定义维度不一致

应该是BFS而不是 DFS ,怎样处理区分这两种遍历:

DFSBFS异同比较

本质区别

BFS 的重点在于队列,而 DFS 的重点在于递归。这是它们的本质区别。

DFS:

BFS算法 
是一种利用队列(用队列来保存未访问的结点,先进先出)实现的搜索算法。

应用方向的不同

BFS 常用于找单一的最短路线,它的特点是搜到就是最优解 
DFS
常用于找所有解的问题,找到的不一定是最优解。

代码:

/*
e2 e4
a1 b2
b2 c3
a1 h8
a1 h7
h8 a1
b1 c3
f6 f6

*/
//标记是否走过该格子 
//应该是BFS而不是 DFS ,怎样处理区分 
#include<stdio.h>
#include<string.h>
//#define LOCAL
#define MAX 8
int mat[MAX+1][MAX+1];//标记是否访问
int dist[MAX+1][MAX+1];//存储距离 
int q[MAX*MAX+1][2];

int dir[]={-2,-1,+1,+2};
void push(int start[2],int rear){
	q[rear][0]=start[0];
	q[rear][1]=start[1];
	return;
}
void pop(int temp[2],int front){
	temp[0]=q[front][0];
	temp[1]=q[front][1];
	return;
}
int find(int start[2],int end[2],int count){
//	printf("end:%d%d\n",end[0],end[1]);
	int front=0,rear=0;
	int temp[2];
	mat[start[0]][start[1]]=1;//vis
	dist[start[0]][start[1]]=0;//dis
	push(start,rear++);
	while(front<rear){
		pop(start,front++);
		if(start[0]==end[0]&&start[1]==end[1]){
			return dist[start[0]][start[1]];
		}
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				temp[0]=start[0]+dir[i];
				temp[1]=start[1]+dir[j];
				//符合骑士规则 且在棋盘内 且没访问过 
				if(dir[i]!=dir[j]&&(dir[j]+dir[i]!=0)
				&&temp[0]>-1&&temp[0]<8&&temp[1]>-1&&temp[1]<8
				&&!mat[temp[0]][temp[1]]){
					push(temp,rear++);
					mat[temp[0]][temp[1]]=1;
					dist[temp[0]][temp[1]]=dist[start[0]][start[1]]+1;
				}
			}
		}
	}
	return -1;
}
int main(){
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif
	char squ1[3],squ2[3];
	int start[2],end[2];
	while(scanf("%s%s",squ1,squ2)==2){
		int count=0;
		memset(mat,0,sizeof(mat));
		start[1]=squ1[1]-'1';//棋盘无0 
		start[0]=squ1[0]-'a';
		end[1]=squ2[1]-'1';
		end[0]=squ2[0]-'a';
		count=find(start,end,count);
		printf("To get from %s to %s takes %d knight moves.\n",squ1,squ2,count);
//		printf("start:%d%d end:%d%d\n",start[0],start[1],end[0],end[1]);
	} 
	return 0;
}

参考文章《DFS和BFS算法》https://blog.csdn.net/BillCYJ/article/details/78976932

猜你喜欢

转载自blog.csdn.net/lagoon_lala/article/details/81148984