poj 1915&&poj 2243 Knight Moves (bfs搜索)

28 篇文章 0 订阅
13 篇文章 0 订阅
Knight Moves
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 21919 Accepted: 10223

Description

Background 
Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast. Can you beat him? 
The Problem 
Your task is to write a program to calculate the minimum number of moves needed for a knight to reach one point from another, so that you have the chance to be faster than Somurolov. 
For people not familiar with chess, the possible knight moves are shown in Figure 1. 

Input

The input begins with the number n of scenarios on a single line by itself. 
Next follow n scenarios. Each scenario consists of three lines containing integer numbers. The first line specifies the length l of a side of the chess board (4 <= l <= 300). The entire board has size l * l. The second and third line contain pair of integers {0, ..., l-1}*{0, ..., l-1} specifying the starting and ending position of the knight on the board. The integers are separated by a single blank. You can assume that the positions are valid positions on the chess board of that scenario.

Output

For each scenario of the input you have to calculate the minimal amount of knight moves which are necessary to move from the starting point to the ending point. If starting point and ending point are equal,distance is zero. The distance must be written on a single line.

Sample Input

3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1

Sample Output

5
28
0

Source

TUD Programming Contest 2001, Darmstadt, Germany
一道非常水的bfs搜索题,思路也很简单,和昨天做的那道 Catch That Cow 思想差不多,本来是很水的一道题,按照自己的思路,一下子就可以敲出代码了,然后测试运用,样例中第二组数据怎么运行都是17,检查了好半天,还是没找到错哪,然后自己又重新敲了一遍代码;再测试数据,样例过了,我提交又是wa,我又仔细检查了好几遍,都是没有找到错误,后来我看了一下别人的代码,我怀疑是我的数组开小了,我的queue数组也只开到1000,visit数组也用的是1000,把queue数组改成了100000终于ac了。。。开始一直wa我都以为是思路错误,但是思路非常的清晰啊,竟然在数组这里犯错误,不应该啊!!!以后不能再犯了,值得注意!!
这道题目的主要思路就是分8个方向进行搜索,搜索到了就输出,没搜索到就入队。
用数组模拟队列比用stl效率高一些;
下面是ac的代码:
#include <cstdio>
#include <cstring>
const int maxn=100000;//开始设立的是1000,导致一直wa啊
typedef struct Queue
{
    int x,y,count;
}Queue;
Queue que[maxn];//用数组模拟队列
bool visit[310][310];
int dir[8][2]={{-2,1},{-2,-1},{-1,2},{-1,-2},{1,2},{1,-2},{2,1},{2,-1}};//方向数组
int l,c,d;
void bfs(int x,int y)
{
    memset(visit,false,sizeof(visit));//初始化
    int front=0,rear=0;
    int fx,fy,i;
    que[rear].x=x;//入队
    que[rear].y=y;
    que[rear++].count=0;
    visit[x][y]=true;
    while(front<rear)//队不为空
    {
        Queue q=que[front++];
        if(q.x==c && q.y==d)//搜索到结果
        {
            printf("%d\n",q.count);
            break;
        }
        for(i=0;i<8;i++)
        {
            fx=q.x+dir[i][0];
            fy=q.y+dir[i][1];
            if(fx>=0 && fy >=0 && fx<l && fy <l && !visit[fx][fy])//限制条件,这里也要注意,很多人在这里wa的
            {
                visit[fx][fy]=true;//标记访问
                que[rear].x=fx;//入队
                que[rear].y=fy;
                que[rear++].count=q.count+1;
            }
        }
    }
}
int main()
{
    int t,a,b;
    scanf("%d",&t);
    while(t--)
    {
        memset(que,0,sizeof(que));
        scanf("%d",&l);
        scanf("%d%d",&a,&b);
        scanf("%d%d",&c,&d);
        bfs(a,b);
    }
    return 0;
}

思路比较简单,下面是我wa的代码,第二组数据通不过,我也找不到错误。。。
#include <cstdio>
#include <cstring>
typedef struct Queue
{
    int x,y;
    int count;
}Queue;
const int maxn=1000;
int dir[8][2]={{-2,1},{-2,-1},{-1,2},{-1,-2},{1,2},{1,-2},{2,1},{2,-1}};
bool visit[maxn][maxn];
Queue queue[maxn];
int c,d,l;
void bfs(int x,int y)
{
    int front=0,rear=0;
    int i,fx,fy;
    queue[rear].x=x;
    queue[rear].y=y;
    queue[rear++].count=0;
    visit[x][y]=1;
    while(front<rear)
    {
        Queue q=queue[front++];
        if(q.x==c && q.y==d)
        {
            printf("%d\n",q.count);
            break;
        }
        for(i=0;i<8;i++)
        {
             fx=q.x+dir[i][0];
             fy=q.y+dir[i][1];
            if( fx>= 0 && fy>= 0 && fx <l && fy <l&& !visit[fx][fy])
            {
                visit[fx][fy]=1;
                queue[rear].x=fx;
                queue[rear].y=fy;
                queue[rear++].count=q.count+1;
            }
        }
    }
}
int main()
{
    int t;
    int a,b;
    scanf("%d",&t);
    while(t--)
    {
        memset(queue,0,sizeof(queue));
        //memset(visit,0,sizeof(visit));
        scanf("%d",&l);
        scanf("%d%d",&a,&b);
        scanf("%d%d",&c,&d);
        bfs(a,b);
    }
    return 0;
}

poj 2243 http://poj.org/problem?id=2243
和这道题也类似,就是把棋盘的范围已经确定了,而且起始的时候给你的是字符,把字符转换过来就和1915一样的啦~;直接把之前的代码改一点就直接水过;
#include <cstdio>
#include <cstring>
const int maxn=1000;
typedef struct Queue
{
    int  x,y,count;
}Queue;
char x1,x2;
int b,d,c;
Queue que[maxn];
bool visit[10][10];
int dir[8][2]={{-2,1},{-2,-1},{-1,2},{-1,-2},{1,2},{1,-2},{2,1},{2,-1}};//方向数组
void bfs(int x,int y)
{
    memset(visit,false,sizeof(visit));
    int front=0,rear=0;
    int fx,fy,i;
    que[rear].x=x;
    que[rear].y=y;
    que[rear++].count=0;
    visit[x][y]=true;
    while(front<rear)
    {
        Queue q=que[front++];
        if(q.x==c && q.y==d)
        {
            printf("To get from %c%d to %c%d takes %d knight moves.\n",x1,b,x2,d,q.count);
            break;
        }
        for(i=0;i<8;i++)
        {
            fx=q.x+dir[i][0];
            fy=q.y+dir[i][1];
            if(fx>=1 && fy >=1 && fx<= 8 && fy <=8 && !visit[fx][fy])//注意这个范围,用26的话就会wa
            {
                visit[fx][fy]=true;
                que[rear].x=fx;
                que[rear].y=fy;
                que[rear++].count=q.count+1;
            }
        }
    }
}
int main()
{
    int a;
    while(scanf("%c%d %c%d",&x1,&b,&x2,&d)!=EOF)
    {
       memset(que,0,sizeof(que));
       a=x1-'a'+1;
       c=x2-'a'+1;
       bfs(a,b);
    }
    return 0;
}
还看到有人直接用数学公式直接a的,有点没理解,效率还比较高;也可以用双向队列,还有一个A*算法(没接触过)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值