hdu1728——逃离迷宫——————【BFS】

解题思路:通过曾经一个计数数组,将所有可到达该点位置的转弯次数更新为最小值,最后通过比较目的位置的转弯次数来判断是否能够到达。

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
int f[4][2] = {{ -1, 0}, {1, 0}, {0, 1}, {0, -1}};
char Map[110][110];
int times[110][110];
const int MAXN = 10000;
struct pos {

    int x, y;
    int dir;        //1,2,3,5,7
    int step;
    pos() {

        step = MAXN;
    }
};
bool BFS ( int m, int n, int k, int x1, int y1, int x2, int y2 ) {

    pos tmp;
    tmp.x = y1, tmp.y = x1;
    tmp.dir = 1;                    //方向为任意方向
    tmp.step = 0;                   //初始化起点转弯为0
    times[tmp.x][tmp.y] = 0;        //初始化起点转弯为0
    queue<pos>Q;
    Q.push ( tmp );
    while ( !Q.empty() ) {

        pos temp;
        temp = Q.front();
        Q.pop();
        if ( temp.step > k ) {

            continue;
        }
        for ( int i = 0; i < 4; i++ ) {

            tmp.x = temp.x + f[i][0];
            tmp.y = temp.y + f[i][1];
            tmp.step = temp.step;        //将当前节点次数化为跟前一个节点相同
            if ( i == 0 )
                tmp.dir = 2;             //规定当前节点的方向
            else if ( i == 1 )
                tmp.dir = 3;
            else if ( i == 2 )
                tmp.dir = 5;
            else
                tmp.dir = 7;
            if ( tmp.x >= 1 && tmp.x <= m && tmp.y >= 1 && tmp.y <= n && Map[tmp.x][tmp.y] == '.' ) {

                if ( tmp.dir % temp.dir != 0 ) {

                    tmp.step  = temp.step + 1;  //方向不同增加转弯次数
                }
                if ( tmp.step > k )
                    continue;                   //次数过多,不入队
                if ( times[tmp.x][tmp.y] >= tmp.step ) {    //如果要走到的那个位置次数大于等于当前节点的次数入队,同时更新

                    times[tmp.x][tmp.y] = tmp.step;
                    Q.push ( tmp );
                }
            }
        }

    }
    if ( times[y2][x2] <= k )
        return true;
    else
        return false;
}
int main() {

    int t;
    cin >> t;
    while ( t-- ) {

        int m, n, k, x1, y1, x2, y2;
        cin >> m >> n;
        for ( int i = 0; i < m + 2; i++ ) {

            for ( int j = 0; j < n + 2; j++ ) {

                times[i][j] = MAXN;
            }
        }
        for ( int i = 1; i <= m; i++ )  {

            for ( int j = 1; j <= n; j++ ) {

                cin >> Map[i][j];

            }
        }
        cin >> k >> x1 >> y1 >> x2 >> y2;
        if ( BFS ( m, n, k, x1, y1, x2, y2 ) ) {
            cout << "yes" << endl;
        }
        else
            cout << "no" << endl;

    }
    return 0;
}
/*

2
5 5
.....
.*.*.
.....
.*.*.
.....
1 1 1 3 4

    这组样例会出现要走的该位置次数等于要扩展到的那个节点次数,这时需要
入队,因为以前扩展到该位置时,方向可能跟这次扩展到的方向不一致,会有次
数差异
*/

此题可以进一步改编,依靠已经搜出来的times数组引申到图论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值