题目大意:
骑士只能在3X2的格子中以对角线的形式走,给定棋盘的大小为8x8,题目输入起点和终点,求骑士从起点走到终点所需的最少步数。
解题思路:
国际象棋中,骑士只能在3x2的格子中以对角线的形式走到下一个点。知道了这一点,然后我们可以画图得出骑士从一个点走到下一个点总共有8个方向,我用一个二维数组dir[8][2]来表示方向,然后用广度优先搜索,声明一个队列,对于一个点,将这个点放到队列中,扫描8个方向,若该方向上的下一个点未走过,则将改点入队,标记。最后就是检验以下终点的步数即可。
感想:
关于这道题,这段时间也遇到很多类似的。我觉得最让我觉得有用的是用一个二维的数组在表示方向,这是我怎么也不会想到的。其他的就都是一些套路了。这个用二维数组来处理方向的算法让我受益匪浅。
代码如下:
#include <iostream> #include <stdio.h> #include <string.h>
#include <queue> using namespace std; int c[9][9]; int dir[8][2] = {{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2}}; typedef struct { int x,y,count; }node; node start,finish; int bfs() { memset(c,0,sizeof(c)); node pre,cur; start.count = 0; queue<node> q; q.push(start); c[start.x][start.y] = 1; while(!q.empty()) { pre = q.front(); q.pop(); if(pre.x == finish.x&&pre.y == finish.y) return pre.count; for(int i = 0; i < 8; i++) { cur.x = pre.x + dir[i][0]; cur.y = pre.y + dir[i][1]; if(cur.x<1||cur.x>8||cur.y<1||cur.y>8)continue; if(c[cur.x][cur.y]==1)continue; c[cur.x][cur.y] = 1; cur.count = pre.count + 1; q.push(cur); } } return -1; } int main() { char row,end; int col,ed; int min; while(scanf("%c",&row)!=EOF) { scanf("%d",&col); getchar(); scanf("%c%d",&end,&ed); getchar(); start.x = row-'a'+1; start.y = col; finish.x = end-'a'+1; finish.y = ed; if(start.x==finish.x&&start.y==finish.y) min = 0; else min = bfs(); printf("To get from %c%d to %c%d takes %d knight moves.\n",row,col,end,ed,min); } return 0; }