HDU 1728 逃离迷宫 BFS(加转弯数)

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <queue>
#include <math.h>
using namespace std ;

#define INF 0xfffffff

struct Node
{
    int x  ;
    int y  ;
    int turn ; //记录转弯处
    int dir ;  //记录方向,分别为0, 1, 2, 3
}n, m ;
char map[105][105] ;
bool flag  ;
int num[105][105] ;   /* num[105][105]记录在(x, y)处转过的弯处*/
int tcase, r, c ;
int K, sx, sy, dx, dy ;  //转弯最大处,起始坐标
int direct[4][2] = {1, 0, 0, -1, -1, 0, 0, 1} ;

int main()
{
    int i, j, k ;
    cin >> tcase ;
    while (tcase --)
    {
        cin >> r >> c ;

        for (i = 1; i <= r; i ++)
            for (j = 1; j <= c; j ++)
                cin >> map[i][j] ;
        scanf ("%d%d%d%d%d", &K, &sy, &sx, &dy, &dx) ;

        for (i = 0; i < 105; i ++)
            for (j = 0; j < 105; j ++)
                num[i][j] = INF ;

        flag = false ;

        num[sx][sy] = -1 ; /*初始化在原点的转弯次为0*/
        queue <Node> Q ;

        for (i = 0; i < 4; i ++) /*初始化从起点到四个方向的状态,进入队列,*/
        {                        /*起始点到四个方向,转过的弯都为0*/
            n.x = sx + direct[i][0] ;
            n.y = sy + direct[i][1] ;
            n.turn = 0 ;         //初始化原点到相邻四个方向的转弯次为0
            n.dir = i ;
            if (n.x > 0 && n.y > 0 && n.x <= r && n.y <= c && map[n.x][n.y] == '.')
            {
                num[n.x][n.y] = 0 ; //初始化原点到相邻四个方向的转弯次为0
                Q.push (n) ;
            }
        }

        while (! Q.empty ())        // 遍历
        {
            m = Q.front () ;
            Q.pop () ;

            for (i = 0; i < 4; i ++)
            {
                n.x = m.x + direct[i][0] ;
                n.y = m.y + direct[i][1] ;
                n.turn = m.turn ;
                if (m.dir != i)         //出队列所在的方向与当前方向不同
                {                       //当前方向为新方向
                    n.dir = i ;         //当前坐标的转弯数+1
                    n.turn = m.turn + 1 ;
                }
                else
                {
                    n.dir = m.dir ;
                }
               if (n.x > 0 && n.y > 0 && n.x <= r && n.y <= c && map[n.x][n.y] == '.' && n.turn <= K)
                {
                    if (num[n.x][n.y] < n.turn)   //相等的情况,这时候方向可能不同,所以不能剪枝
                        continue ;
                    num[n.x][n.y] = n.turn ;     /*否则赋值新的转弯处(注意,起始的转弯数为INF)*/
                    Q.push (n) ;
                }
            }
        }
        if (num[dx][dy] <= K)    /* 如果到达过该处,转弯数肯定为某值,否则,该转弯数肯定为INF,即到达不了*/
            printf ("yes\n") ;
        else
            printf ("no\n") ;
    }
    return 0 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值