杭电--1372 Knight Moves (经典BFS)

本题链接:点击打开链接

Knight Moves

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 11362    Accepted Submission(s): 6678


Problem Description
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.".
 

Sample Input
  
  
e2 e4 a1 b2 b2 c3 a1 h8 a1 h7 h8 a1 b1 c3 f6 f6
 

Sample Output
  
  
To get from e2 to e4 takes 2 knight moves. To get from a1 to b2 takes 4 knight moves. To get from b2 to c3 takes 2 knight moves. To get from a1 to h8 takes 6 knight moves. To get from a1 to h7 takes 5 knight moves. To get from h8 to a1 takes 6 knight moves. To get from b1 to c3 takes 1 knight moves. To get from f6 to f6 takes 0 knight moves.
 

Source
 

Recommend
Eddy   |   We have carefully selected several similar problems for you:   1253  1072  1242  1548  1180 
 
 

PS:本人写的第一个广搜题目,看了很多有关广搜的知识,本题就是用队列知识做的,查阅了许多资料,也看了书,现在对队列知识做下笔记,和大家分享下,也方便自己回顾。

首先我们应该都知道C++队列是一种容器适配器,它符合“先进先出“(First In First Out,FIFO)的数据结构,是一种“公平队列”。

涉及到的头文件: #include <queue>  #include <functional>.

队列的建立:   queue<int>+队列名

常用操作:

1.队列名.back()                         返回一个引用,指向最后一个元素(即为取队尾元素)
2.队列名.empty()                       如果队列空则返回为true,否则为false
3.队列名.front()                         返回第一个元素 (即为取对头元素)
4.队列名.pop()                          删除第一个元素 (即为元素出队操作)
5.队列名.push()                         在末尾加入一个元素(即为元素入队操作)
6.队列名.size()                          返回队列中元素的个数
7.队列名.top()                           返回优先队列中有最高优先级的元素(优先队列中需要用到的)

 

题意:给出骑士的初始位置和目标位置,计算要移动多少步到达目标位置。按照格式输出即可。

 

分析:只要我们知道国际象棋中的骑士和中国的象棋中的“马”差不多一样就行,它每次的移动方式也是“日”,唯一一点不同就是没有拌马脚。

 

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
char a[5],b[5];
int vis[10][10];                     //标记数组,记录已经走过的位置(用bool型也可)
int dir[8][2]= {{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};//骑士每次可以移动的八个方向
int sx,sy,ex,ey,t;                   //sx,sy,es,ey分别代表骑士初始位置和目标位置,t记录走的步数
struct node
{
    int x,y,temp;
} s,ns;
void bfs(int x,int y)
{
    int i,nx,ny;
    queue<node>q;                    //将队列名设为q;
    s.x=x;
    s.y=y;
    s.temp=0;
    vis[x][y]=0;
    q.push(s);                       //将第一个元素加入队列中
    while(!q.empty())
    {
        s=q.front();                 //再取出队列中的第一个元素赋值给结构体变量s
        q.pop();                     //删除第一个元素
        if(s.x==ex&&s.y==ey)         //判断是否已到达目标位置
        {
            t=s.temp;
            return;
        }
        for(i=0; i<8; i++)           //开始游历查找目标位置
        {
            nx=s.x+dir[i][0];
            ny=s.y+dir[i][1];
            if(vis[nx][ny]&&nx>0&&nx<9&&ny>0&&ny<9)     //注意是否越界和已游历
            {
                ns.x=nx;
                ns.y=ny;
                ns.temp=s.temp+1;
                vis[nx][ny]=0;          //已经游历就标记为0
                q.push(ns);             //将下一位置元素压入队列中进行判断
            }
        }
    }
}
int main()
{
    while(~scanf("%s%s",a,b))
    {
        memset(vis,1,sizeof(vis));   //记得每次初始化标记数组
        sx=a[0]-'a'+1;               //因为输入的是字符,所以需要处理一下。
        sy=a[1]-'0';
        ex=b[0]-'a'+1;
        ey=b[1]-'0';
        bfs(sx,sy);
        printf("To get from %s to %s takes %d knight moves.\n",a,b,t);
    }
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值