poj3083

Problem: Children of the Candy Corn

Description:给你一个迷宫,#号代表墙壁,.号代表空白可以走,S是入口,E是出口。问左边优先(即顺序为左上右下)找到出口需要多少步,右边优先(即顺序为右上左下)找到出口需要多少步,还有找到出口所需要的最短步数。

Solution: 找最短步数要用到广搜,关键是沿着它规定的方向走不好判断,要弄清楚它是怎么转的就好了。

单就沿着左走看一下:
当前方向    检索顺序

 ↑ :      ← ↑ → ↓

→ :        ↑ → ↓ ← 

 ↓ :      → ↓ ← ↑ 

← :        ↓ ← ↑ → 

因为每次开始时方向并不是一定是左上右下,所以我们需要定义一个参数来记录当前的方向。

Code(C++):

#include <iostream>
#include <cstring>
#include <queue>
#define Max 45

using namespace std;

char maze[Max][Max];
int visit[Max][Max];
int m,n;

struct point
{
    int x;
    int y;
    int step;
    point() {}
    point(int x,int y,int step)
    {
        x=this->x;
        y=this->y;
        step=0;
    }
} pr[4],pl[4];


bool Dfs(point pi,point p[],int dic,int &k)
{
    k++;
    int j;
    point next;
    if(maze[pi.x][pi.y]=='E')
        return true;
    for(int i=0; i<4; i++)
    {
        j=((dic+3)%4+i)%4;
        next.x=pi.x+p[j].x;
        next.y=pi.y+p[j].y;
        if((maze[next.x][next.y]=='.'&&next.x>=0
                &&next.y>=0&&next.x<m&&next.y<n)||(maze[next.x][next.y]=='E'))
        {
            if(Dfs(next,p,j,k))
                return true;
            k--;
        }
    }
}

bool Bfs(point pi,point p[],int vit[Max][Max],int &k)
{
    queue<point>q;
    point next;
    q.push(pi);
    while(!q.empty())
    {
        point tmp=q.front();
        q.pop();
        for(int i=0; i<4; i++)
        {
            next.x=tmp.x+p[i].x;
            next.y=tmp.y+p[i].y;
            next.step=tmp.step+1;
            if(maze[next.x][next.y]=='E')
            {
                k=next.step;
                return true;
            }
            if(maze[next.x][next.y]=='.'&&vit[next.x][next.y]==0
                    &&next.x>=0&&next.y>=0&&next.x<m&&next.y<n)
            {
                vit[next.x][next.y]=1;
                q.push(next);
            }
        }
    }
}

int main()
{
    int N,cnt;
    int cntl,cntr,a,b;
    point index;

    //左边优先
    pl[0].x=0,pl[0].y=-1;//左
    pl[1].x=-1,pl[1].y=0;//上
    pl[2].x=0,pl[2].y=1;//右
    pl[3].x=1,pl[3].y=0;//下

    //右边优先
    pr[0].x=0,pr[0].y=1;//右
    pr[1].x=-1,pr[1].y=0;//上
    pr[2].x=0,pr[2].y=-1;//左
    pr[3].x=1,pr[3].y=0;//下
    cin>>N;
    while(N--)
    {
        memset(visit,0,sizeof(visit));
        cntl=1,cntr=1;
        cnt=1;
        cin>>n>>m;
        for(int i=0; i<m; i++)
            for(int j=0; j<n; j++)
            {
                cin>>maze[i][j];
                if(maze[i][j]=='S')
                    a=i,b=j;
            }
        index.x=a,index.y=b,index.step=0;
        visit[a][b]=1;
        Dfs(index,pl,-3,cntl);
        Dfs(index,pr,-3,cntr);
        Bfs(index,pl,visit,cnt);
        cout<<cntl-1<<" "<<cntr-1<<" "<<cnt+1<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值