现在的位置: 首页 > 综合 > 正文

hdu 1728 逃离迷宫(bfs)

2017年11月23日 ⁄ 综合 ⁄ 共 1213字 ⁄ 字号 评论关闭

小记:这题题意开始理解出错了,然后一直WA,TLE,我以为只要在一条水平或垂直线上走就不算转弯次数, 然后就是在每一点可以从各个方向进入,但是必须是不同方向才能入队。我就是认为水平或垂直不算转弯次数,所以一直TLE,对每点保存的是最小需要转弯的次数,最开始我太天真了,直接是以点坐标判重的,后来WA后,想通了。

思路:bfs 每点需要最小的转弯数,判重的方法是对每点记录需要的转弯数,保留最小的,非最小的不需入队。 每个节点记录是从哪个方向来的。

代码简单,看看就可以理清思路了:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

const int MAX_ = 10001;
const int INF = 100000000;

int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};

int n,m,cnt;
int f[101][101];
int num[101][101];

struct point {
    int x,y,step;
    int pre;
} s,e,t;


void bfs() {
    queue<point>q;
    q.push(s);
    while(!q.empty()) {
        point cur, next;
        cur = q.front();
        q.pop();
        if(cur.x == t.x && cur.y == t.y)return ;
        for(int i = 0; i < 4; ++i) {
            next.x = cur.x + dir[i][0];
            next.y = cur.y + dir[i][1];
            next.step = cur.step;
            next.pre = i;

            if((next.x >= 1 && next.x <= n) && (next.y >= 1 && next.y <= m) &&(f[next.x][next.y] != 1)) {

                if(cur.pre != -1 && cur.pre != i) {//
                        next.step ++;
                }
                if(next.step > cnt)continue;//两步很重要
                if(num[next.x][next.y] >= next.step) {
                    num[next.x][next.y] = next.step;
                    q.push(next);
                }
            }
        }
    }
}

int main() {
    int T;
    char c;
    cin>>T;
    while(T--) {
        cin>>n>>m;
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= m; ++j) {
                cin>>c;
                c == '.'?f[i][j] = 0:f[i][j] = 1;
                num[i][j] = INF;
            }
        }

        cin>>cnt>>s.y>>s.x>>t.y>>t.x;
        s.pre = -1;
        s.step = 0;
        num[s.x][s.y] = 0;
        bfs();
        if(num[t.x][t.y] <= cnt)cout<<"yes";
        else  cout<<"no";
        cout<<endl;
    }
    return 0;
}

抱歉!评论已关闭.