HDU 1327 Knight Moves

23 篇文章 0 订阅
17 篇文章 0 订阅
Knight Moves

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


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.


广搜加强版,之前做过计算两个数之间最短距离的,是3个方向的,这道题是两点之间的距离,8个方向的。

这道题先将数据转换,将以字符的形式做标记的转化为数字形式来记录位置,

然后将初始点推入队列中,将队首的元素向周围8个方向晕染,在脑海中想象一个点晕染了周围的8个方向,将晕染成灰色点了的颜色推入队列中,之前已经是灰色的点就指挥不了她了,这个点不能入队列,队首的点变成黑的,这时候这个点就变强大了,继续晕染周围的8个点,继续碰到灰色的就已经是自己人了,不用让他变灰,是白色的敌方的人就让他归为自己人,想那个病毒传播一样,哈哈。这里对于已经变灰了的不能再让他变灰的概念就是:已经走过的点如果再到这个点上来的话,她还是会重复走这个点原来的路径的,只能在走循环,一直在走原来的路,退不出来,会造成死循环的,这里也是给一个终止的条件。最后第一次走到给定点的位置的时候,就是最短距离啦。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
struct point
{
    int x,y;
}point;
int b[105][105],a[105][105];
int main(void)
{
   // freopen("C.txt","r",stdin);
    int endx,endy;
    char c1,c2;
    while(scanf("%c%d %c%d",&c1,&point.x,&c2,&endx)!=EOF)
    {
        getchar();
      //  printf("%c %d %c %d\n",c1,point.x,c2,endx);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        queue<struct point> p;
        point.y=c1-'a'+1;
        endy=c2-'a'+1;
        p.push(point);
        b[point.x][point.y]=1;
        while(!p.empty())
        {
            struct point tmp;
            tmp.x=p.front().x;tmp.y=p.front().y;
            p.pop();
            if(tmp.x==endx&&tmp.y==endy) break;
            if(a[tmp.x-2][tmp.y+1]<=100&&b[tmp.x-2][tmp.y+1]==0&&tmp.x-2>=1&&tmp.x-2<=8&&tmp.y+1>=1&&tmp.y+1<=8)
            {
                a[tmp.x-2][tmp.y+1]=a[tmp.x][tmp.y]+1;
                b[tmp.x-2][tmp.y+1]=1;
                struct point t;
                t.x=tmp.x-2;
                t.y=tmp.y+1;
                p.push(t);
            }
            if(a[tmp.x-1][tmp.y+2]<=100&&b[tmp.x-1][tmp.y+2]==0&&tmp.x-1>=1&&tmp.x-1<=8&&tmp.y+2>=1&&tmp.y+2<=8)
            {
                a[tmp.x-1][tmp.y+2]=a[tmp.x][tmp.y]+1;
                b[tmp.x-1][tmp.y+2]=1;
                struct point t;
                t.x=tmp.x-1;
                t.y=tmp.y+2;
                p.push(t);
            }
            if(a[tmp.x+1][tmp.y+2]<=100&&b[tmp.x+1][tmp.y+2]==0&&tmp.x+1>=1&&tmp.x+1<=8&&tmp.y+2>=1&&tmp.y+2<=8)
            {
                a[tmp.x+1][tmp.y+2]=a[tmp.x][tmp.y]+1;
                b[tmp.x+1][tmp.y+2]=1;
                struct point t;
                t.x=tmp.x+1;
                t.y=tmp.y+2;
                p.push(t);
            }
            if(a[tmp.x+2][tmp.y+1]<=1000&&b[tmp.x+2][tmp.y+1]==0&&tmp.x+2>=1&&tmp.x+2<=8&&tmp.y+1>=1&&tmp.y+1<=8)
            {
                a[tmp.x+2][tmp.y+1]=a[tmp.x][tmp.y]+1;
                b[tmp.x+2][tmp.y+1]=1;
                struct point t;
                t.x=tmp.x+2;
                t.y=tmp.y+1;
                p.push(t);
            }
            if(a[tmp.x+2][tmp.y-1]<=1000&&b[tmp.x+2][tmp.y-1]==0&&tmp.x+2>=1&&tmp.x+2<=8&&tmp.y-1>=1&&tmp.y-1<=8)
            {
                a[tmp.x+2][tmp.y-1]=a[tmp.x][tmp.y]+1;
                b[tmp.x+2][tmp.y-1]=1;
                struct point t;
                t.x=tmp.x+2;
                t.y=tmp.y-1;
                p.push(t);
            }
            if(a[tmp.x+1][tmp.y-2]<=1000&&b[tmp.x+1][tmp.y-2]==0&&tmp.x+1>=1&&tmp.x+1<=8&&tmp.y-2>=1&&tmp.y-2<=8)
            {
                a[tmp.x+1][tmp.y-2]=a[tmp.x][tmp.y]+1;
                b[tmp.x+1][tmp.y-2]=1;
                struct point t;
                t.x=tmp.x+1;
                t.y=tmp.y-2;
                p.push(t);
            }
            if(a[tmp.x-1][tmp.y-2]<=1000&&b[tmp.x-1][tmp.y-2]==0&&tmp.x-1>=1&&tmp.x-1<=8&&tmp.y-2>=1&&tmp.y-2<=8)
            {
                a[tmp.x-1][tmp.y-2]=a[tmp.x][tmp.y]+1;
                b[tmp.x-1][tmp.y-2]=1;
                struct point t;
                t.x=tmp.x-1;
                t.y=tmp.y-2;
                p.push(t);
            }
            if(a[tmp.x-2][tmp.y-1]<=1000&&b[tmp.x-2][tmp.y-1]==0&&tmp.x-2>=1&&tmp.x-2<=8&&tmp.y-1>=1&&tmp.y-1<=8)
            {
                a[tmp.x-2][tmp.y-1]=a[tmp.x][tmp.y]+1;
                b[tmp.x-2][tmp.y-1]=1;
                struct point t;
                t.x=tmp.x-2;
                t.y=tmp.y-1;
                p.push(t);
            }
        }
        printf("To get from %c%d to %c%d takes %d knight moves.\n",c1,point.x,c2,endx,a[endx][endy]);

    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值