Knight Moves

Knight Moves poj-1915

    题目大意:在国际象棋中有一个骑士,想从一个点到达另一个点。骑士可以从2*3的矩阵的一角跳到对角线的另一角。问:骑士最少需要跳多少次才能从一个点跳到另一个点。

    注释:棋盘大小l为1<=l<=300.

      想法:显然,这是一道非常经典的宽度优先搜索的题目(bfs)。我们通过起始点开始宽搜:对于当前点来讲,我们通过数组记录骑士可以到达的8个方向,并且判断骑士向每个方向跳跃是否仍然在棋盘内。如果骑士到达了当前点,我们将当前点标记为true。显然,如果后来骑士跳跃到了一个已经被标记过的点,显然是要相较于之前的枚举更加差的。紧接着,我们维护一个数组ans[i][j]表示从起始点到(i,j)需要的步数。最后,我们只需要输出答案即可。

    最后,附上丑陋的代码... ...

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 using namespace std;
 7 int map[350][350];
 8 int ans[350][350];
 9 int n;
10 int sx,sy,ex,ey;
11 int a[8][2]= {1,2,1,-2,-1,2,-1,-2,2,1,2,-1,-2,1,-2,-1};
12 struct Node
13 {
14     int xx,yy;
15 };
16 Node Mid,p;
17 queue q;
18 inline int bfs()
19 {
20     queue q;
21     int x,y;
22     memset(map,0,sizeof(map));
23     memset(ans,0,sizeof(ans));
24     Mid.xx=sx;
25     Mid.yy=sy;
26     map[sx][sy]=1;
27     q.push(Mid);
28     while(!q.empty())
29     {
30         Mid=q.front();
31         x=Mid.xx;
32         y=Mid.yy;
33         q.pop();
34         if(x==ex&&y==ey) break;
35         int x_,y_;
36         for(int i=0; i<8; i++)
37         {
38             x_=x+a[i][0];
39             y_=y+a[i][1];
40             if(x_>=0&&y_>=0&&x_0)
41             {
42                 ans[x_][y_]=ans[x][y]+1;
43                 p.xx=x_;
44                 p.yy=y_;
45                 q.push(p);
46                 map[x_][y_]=1;
47             }
48         }
49     }
50 }
51 int main()
52 {
53     int cases;
54     scanf("%d",&cases);
55     while(cases--)
56     {
57         scanf("%d",&n);
58         scanf("%d%d%d%d",&sx,&sy,&ex,&ey);
59         bfs();
60         printf("%d\n",ans[ex][ey]);
61     }
62     return 0;
63 }

    小结:第二道bfs。注意队列要开在函数里,不然的话会WA。

转载于:https://www.cnblogs.com/ShuraK/p/8470583.html

你可能感兴趣的:(Knight Moves)