Poj 1915 - Knight Moves 双向广搜

 1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int vis[305][305], mat[305][305];
5 int dx[] = {-2, -2, -1, 1, 2, 2, 1, -1};
6 int dy[] = {-1, 1, 2, 2, 1, -1, -2, -2};
7 int casenum, nNum, sx, sy, tx, ty, i;
8
9 struct point
10 {
11 int x, y;
12 }cur, next, q[90005]={0};
13
14 int IsInBound(int x, int y)
15 {
16 return (x>=0 && y>=0 && x<nNum && y<nNum);
17 }/* IsInBound */
18
19 int Solve()
20 {
21 int rear = -1;
22 int front = -1;
23
24 cur.x = sx;
25 cur.y = sy;
26 vis[sx][sy] = 1; /* 从起始位置开始的探索标记为 1 */
27 q[++rear] = cur; /* 起始坐标入队 */
28
29 next.x = tx;
30 next.y = ty;
31 vis[tx][ty] = 2; /* 从终点位置开始的探索标记为 2 */
32 q[++rear] = next; /* 终点坐标入队 */
33
34 while (front < rear)
35 {
36 cur = q[++front]; /* 队首节点坐标出队 */
37
38 for (i=0; i<8; ++i)
39 {
40 next.x = cur.x + dx[i];
41 next.y = cur.y + dy[i];
42
43 if (!IsInBound(next.x, next.y))
44 continue;
45
46 if (!vis[next.x][next.y])
47 {
48 vis[next.x][next.y] = vis[cur.x][cur.y]; /* 设为与当前探索路径相同的标记 */
49 mat[next.x][next.y] = mat[cur.x][cur.y] + 1; /* 记录步数 */
50 q[++rear] = next; /* 当前合法坐标位置入队 */
51 }
52 else if (vis[cur.x][cur.y] != vis[next.x][next.y])
53 { /* 说明从起点出发的探索与从终点出发的探索重合 */
54 return mat[cur.x][cur.y]+mat[next.x][next.y]+1;
55 }
56 }/* End of For */
57 }/* End of While */
58 }/* Solve */
59
60 int main()
61 {
62 scanf("%d", &casenum);
63 while (casenum--)
64 {
65 memset(vis, 0, sizeof(vis));
66 memset(mat, 0, sizeof(mat));
67
68 scanf("%d", &nNum);
69 scanf("%d %d", &sx, &sy);
70 scanf("%d %d", &tx, &ty);
71
72 if (sx==tx && sy==ty)
73 {
74 printf("0\n");
75 }
76 else
77 {
78 printf("%d\n", Solve());
79 }
80 }/* End of While */
81
82 return 0;
83 }

 

你可能感兴趣的:(move)