Poj 1915 - Knight Moves 双向广搜

 #include <stdio.h>
 #include <stdlib.h>
 
 int vis[305][305], mat[305][305];
 int dx[] = {-2, -2, -1, 1, 2, 2, 1, -1};
 int dy[] = {-1, 1, 2, 2, 1, -1, -2, -2};
 int casenum, nNum, sx, sy, tx, ty, i;
 
 struct point
 {
     int x, y;
 }cur, next, q[90005]={0};
 
 int IsInBound(int x, int y)
 {
     return (x>=0 && y>=0 && x<nNum && y<nNum);
 }/* IsInBound */
 
 int Solve()
 {
     int rear = -1;
     int front = -1;
     
     cur.x = sx;
     cur.y = sy;
     vis[sx][sy] = 1; /* 从起始位置开始的探索标记为 1 */ 
     q[++rear] = cur; /* 起始坐标入队 */ 
     
     next.x = tx;
     next.y = ty;
     vis[tx][ty] = 2;  /* 从终点位置开始的探索标记为 2 */ 
     q[++rear] = next; /* 终点坐标入队 */ 
     
     while (front < rear)
     {
         cur = q[++front]; /* 队首节点坐标出队 */
         
         for (i=0; i<8; ++i)
         {
             next.x = cur.x + dx[i];
             next.y = cur.y + dy[i];
             
             if (!IsInBound(next.x, next.y))
                 continue;
                 
             if (!vis[next.x][next.y])
             {
                 vis[next.x][next.y] = vis[cur.x][cur.y];     /* 设为与当前探索路径相同的标记 */
                 mat[next.x][next.y] = mat[cur.x][cur.y] + 1; /* 记录步数 */ 
                 q[++rear] = next; /* 当前合法坐标位置入队 */ 
             }
             else if (vis[cur.x][cur.y] != vis[next.x][next.y])
             {   /* 说明从起点出发的探索与从终点出发的探索重合 */ 
                 return mat[cur.x][cur.y]+mat[next.x][next.y]+1;
             }
         }/* End of For */
     }/* End of While */
 }/* Solve */
 
 int main()
 {
     scanf("%d", &casenum);
     while (casenum--)
     {
         memset(vis, 0, sizeof(vis));
         memset(mat, 0, sizeof(mat));
         
         scanf("%d", &nNum);
         scanf("%d %d", &sx, &sy);
         scanf("%d %d", &tx, &ty);
         
         if (sx==tx && sy==ty)
         {
             printf("0\n");
         }
         else
         {
             printf("%d\n", Solve());
         }    
     }/* End of While */
     
     return 0;
 }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值