poj-3083 (90行代码)

bfs+dfs

题意搞了半天才明白,原来就是给你一个类似于迷宫,#不能走,然后问你从S出发到达E需要多少步。
需要注意的是题目规定了三种走法:dfs(左优先、右优先两种)和bfs(一种)。
那么问题来了,既然前两种方法同样是dfs,经过思考之后发现可以合并。
方位数组dir一定要按照顺序写,以左优先为例:假设人的初始位置为面朝北(默认上北下南),那么此时左为西方,如果西方不能走,人就会调头(此时面朝东),这时左边为北。于是定义左优先的dir数组时应按照顺时针定义,反之,右优先dir数组应按照逆时针定义。这时不难想到,类似于bfs的dir数组,不过可以定义为三维,第一维0表示左优先,1表示右优先
代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
struct node
{
    int x, y, f;
};
int m, n, sx, sy, ex, ey, vis[50][50];//vis数组为标记数组
char mat[50][50];//用于存储输入的地图
int dir[2][4][2] = {{{0,-1},{-1,0},{0,1},{1,0}},{{0,1},{-1,0},{0,-1},{1,0}}};//方位数组
bool judge(int x, int y)//检查是否符合要求
{
    if(x >= 0 && x < m && y >= 0 && y < n && mat[x][y] != '#')
        return true;
    return false;
}
int dfs(int curdir, int index, int x, int y, int step)//curdir表示当前方位,index为0表示左优先,1表示右优先
{
    if(x == ex && y == ey)//到达E
        return step;
    for(int i = curdir; i < curdir+4; i++)
    {
        int tx = x+dir[index][i%4][0];
        int ty = y+dir[index][i%4][1];
        if(judge(tx, ty))
        {
            dfs((i+3)%4, index, tx, ty, step+1);//当前方位为i%4,如果符合要求,方位应减一
            break;
        }
    }
}
int bfs()//标准的bfs
{
    queue<node>q;
    node s, e;
    memset(vis, 0, sizeof(vis));
    s.x = sx;
    s.y = sy;
    s.f = 0;
    q.push(s);
    vis[sx][sy] = 1;
    while(!q.empty())
    {
        s = q.front();
        q.pop();
        for(int i = 0; i < 4; i++)
        {
            e.x = s.x + dir[0][i][0];
            e.y = s.y + dir[0][i][1];
            e.f = s.f+1;
            if(e.x == ex && e.y == ey)
                return e.f;
            if(judge(e.x, e.y) && !vis[e.x][e.y])
            {
                vis[e.x][e.y] = 1;
                q.push(e);
            }
        }
    }
    return -1;
}
int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        scanf("%d %d", &n, &m);
        for(int i = 0; i < m; i++)
            scanf("%s", mat[i]);
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
            {
                if(mat[i][j] == 'S')
                    sx = i,sy = j;
                if(mat[i][j] == 'E')
                    ex = i, ey = j;
            }
        printf("%d %d %d\n", dfs(0, 0, sx, sy, 1), dfs(0, 1, sx, sy, 1), bfs()+1);//S也算一步
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值