poj 3083

解决好方向问题就ok


#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

#define met(a, b) memset(a, b, sizeof(a))

const int N = 45;

bool flag;
char g[N][N];
int m, n, ans, vis[N][N];
int dir[4][2] = {0, -1, -1, 0, 0, 1, 1, 0};
struct node {int x, y, t;};

void dfs (int x, int y, int x1, int y1, int d);
void bfs (node sa, node en);

int main ()
{
    int t;
    cin >> t;
    while (t--)
    {
        node sa, en;
        cin >> n >> m;
        for (int i=0; i<m; i++)
            for (int j=0; j<n; j++)
        {
            cin >> g[i][j];
            if (g[i][j] == 'S') sa = (node){i, j};
            if (g[i][j] == 'E') en = (node){i, j};
        }
        ans = 1; flag = false;
        dfs (sa.x, sa.y, en.x, en.y, 0);
        cout << ans << " ";
        ans = 1; flag = false;
        dfs (en.x, en.y, sa.x, sa.y, 0);
        cout << ans << " ";
        met (vis, false);
        bfs (sa, en);
    }
    return 0;
}

void dfs (int x, int y, int x1, int y1, int d)
{
    if (flag) return;
    if (x == x1 && y == y1) {flag = true; return;}

    d = (d + 3) % 4;

    for (int i=d; i<d+4; i++)
    {
        int xx = x + dir[i%4][0], yy = y + dir[i%4][1];
        if (xx >= 0 && xx < m && yy >= 0 && yy < n && g[xx][yy] != '#')
        {
            ans++;
            dfs (xx, yy, x1, y1, i%4);
            if (flag) return;
        }
    }
}

void bfs (node sa, node en)
{
    queue <node> que;
    sa.t = 1;
    que.push(sa);
    vis[sa.x][sa.y] = true;
    while (que.size())
    {
        sa = que.front(); que.pop();
        if (sa.x == en.x && sa.y == en.y) {cout << sa.t << endl; return;}
        for (int i=0; i<4; i++)
        {
            node q = sa;
            q.x += dir[i][0], q.y += dir[i][1];
            if (q.x >= 0 && q.x < m && q.y >= 0 && q.y < n && !vis[q.x][q.y] && g[q.x][q.y] != '#')
            {
                vis[q.x][q.y] = true;
                q.t = sa.t + 1;
                que.push(q);
            }
        }
    }
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值