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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值