CTU 2012 Gregory the Grass hopper(BFS)


テーマリンク:  http://contest.felk.cvut.cz/12prg/solved.html
タイトルの大意:    一つの点から最後までもう一つの点の最短時間を求めます.
                    しかし、歩く道は隣の格子ではなく、中国将棋の馬のように「日」の字を歩きます.
                    単位時間は一回しか歩けません.最短時間はいくらですか?
                    歩く過程で境界範囲を超えてはいけません.
問題解決の考え方:  この問題はpoj 2234 Knight Movesと同じ考えです.
                    原点から広く検索し、毎回8つの位置を検索します.
                           図のように(将棋の馬が日本語を走るような)
                    一歩進むごとに、次のステップのステップ数は前のステップに1を加えることになります.終点まで行くとすぐに終了します.
                    その点に行くと、この点の周りの8つの場所を全部回ってみます.
                    今度はここを歩く必要がないです.歩いて帰ってもいいところは前回はきっと通り過ぎました.
                    だからこの問題はSPFAを使う必要がありません.
                    この問題は双方向BFSも使えますが、大量のテストをしたことがあります.このような最も短絡的な問題に対して、双方向BFSの効果はあまりはっきりしません.
コード:
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#define MAX 101
int n,m,edge[MAX][MAX];
typedef struct node{
    int x;
    int y;
}snode;
snode fx[8]={{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2}},list[MAX*MAX];

int BFS(int sx,int sy,int ex,int ey)
{
    int i,tempx,tempy,temp1x,temp1y,e,s;
    e=s=0;
    edge[sx][sy]=0;  //   
    list[s].x=sx;
    list[s++].y=sy;
    while(e!=s)      //     
    {
        tempx=list[e].x;     //  
        tempy=list[e++].y;
        for(i=0;i<8;i++)     //    
        {
            temp1x=tempx+fx[i].x;
            temp1y=tempy+fx[i].y;
            if(temp1x==ex&&temp1y==ey)
            {
                edge[temp1x][temp1y]=edge[tempx][tempy]+1;
                return edge[temp1x][temp1y];
            }
            if(temp1x>=1&&temp1x<=n&&temp1y>=1&&temp1y<=m&&edge[temp1x][temp1y]==-1)
            {                //     ,          ,   
                edge[temp1x][temp1y]=edge[tempx][tempy]+1;
                list[s].x=temp1x;
                list[s++].y=temp1y;
            }
        }
    }
    return -1;
}

int main()
{
    int sx,sy,ex,ey;
    while(scanf("%d%d%d%d%d%d",&n,&m,&sx,&sy,&ex,&ey)!=EOF)
    {
        memset(edge,-1,sizeof(edge));
        if(sx==ex&&sy==ey)   //             0 
        {
            printf("0
"); continue; } if(BFS(sx,sy,ex,ey)==-1) printf("impossible
"); else printf("%d
",edge[ex][ey]); } return 0; }
注:オリジナル文章、転載は出典を明記してください.