糖果玉米的孩子

描述

玉米田迷宫是一种受欢迎的万圣节款待。参观者可以看到入口,必须在面对僵尸,电锯挥舞的精神病患者,嬉皮士和其他恐怖的迷宫中漫步,寻找出口。 

一种流行的迷宫步行策略可确保访客最终找到出口。只需选择右侧或左侧墙壁,然后按照它即可。当然,不能保证哪种策略(左或右)会更好,而且所采用的路径很少是最有效的。(它也不适用于不在边缘的出口的迷宫;这个类型的迷宫没有在这个问题中表示。) 

作为即将被转换为迷宫的玉米田的主人,你想要一个能够确定左右路径以及最短路径的计算机程序,以便你可以找出哪个布局具有混淆游客的最佳机会。

输入

对此问题的输入将以包含单个整数n的行开始,该整数n表示迷宫的数量。每个迷宫将由一条宽度为w,高度为h的线组成(3 <= w,h <= 40),然后是h行w字符,每行代表迷宫布局。墙由散列标记('#')表示,空格按句点('。')表示,开头用'S'表示,退出用'E'表示。 

正好一个'S'和一个'E'将出现在迷宫中,它们将始终位于迷宫边缘之一,而不是一个角落。迷宫将被墙壁('#')完全包围,唯一的开口是'S'和'E'。'S'和'E'也将被至少一个墙('#')隔开。 

 

产量

对于输入中的每个迷宫,在单行上输出一个人将(按顺序)左,右和最短路径访问(包括'S'和'E')的(不一定是唯一的)方格的数量,每个单独的空格分隔。只允许在水平或垂直方向上从一个方格移动到另一个方格; 沿着对角线的运动是不允许的。

样本输入

 

2
8 8
########
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S#E####
9 5
#########
#.#.#.#.#
S.......E
#.#.#.#.#
#########

Sample Output

37 5 5
17 17 9

左转优先和右转优先用的深搜,最短路径用的广搜

#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
int x,y,ex,ey;
struct zuobiao
{
    int x,y;
}now,nex;
int m,n;
int step,step2;
char a[50][50];
int mark[50][50];
int output[50][50];
int vis[50][50];
int fx[4]={0,0,-1,1};
int fy[4]={1,-1,0,0};
int bfs(int x,int y)
{
    memset(output,0,sizeof(output));
    memset(vis,0,sizeof(vis));
    vis[x][y]=1;
    queue<zuobiao >s;
    now.x=x;
    now.y=y;
    output[x][y]=1;
    s.push(now);
    while(!s.empty())
    {
        now=s.front();
        if(a[now.x][now.y]=='E')
        {
            return output[now.x][now.y];
        }
        s.pop();
        for(int i=0;i<4;i++)
        {
            nex.x=now.x+fx[i];
            nex.y=now.y+fy[i];
            if(nex.x>=0&&nex.x<n&&nex.y>=0&&nex.y<m&&vis[nex.x][nex.y]==0&&a[nex.x][nex.y]!='#')
            {
                s.push(nex);
                output[nex.x][nex.y]=output[now.x][now.y]+1;
                vis[nex.x][nex.y]=1;
            }
        }
    }
    return -1;
}
void dfs(int i,int j,int d)   //左转深搜
{
    step++;
    if(i==ex&&j==ey)return ;
    if(d==0)
    {
        if(mark[i][j-1])dfs(i,j-1,1);
        else if(mark[i-1][j])dfs(i-1,j,0);
        else if(mark[i][j+1])dfs(i,j+1,3);
        else dfs(i+1,j,2);
    }
    if(d==1)
    {
        if(mark[i+1][j])dfs(i+1,j,2);
        else if(mark[i][j-1])dfs(i,j-1,1);
        else if(mark[i-1][j])dfs(i-1,j,0);
        else dfs(i,j+1,3);
    }
    if(d==2)
    {
        if(mark[i][j+1])dfs(i,j+1,3);
        else if(mark[i+1][j])dfs(i+1,j,2);
        else if(mark[i][j-1])dfs(i,j-1,1);
        else dfs(i-1,j,0);
    }
    if(d==3)
    {
        if(mark[i-1][j])dfs(i-1,j,0);
        else if(mark[i][j+1])dfs(i,j+1,3);
        else if(mark[i+1][j])dfs(i+1,j,2);
        else dfs(i,j-1,1);
    }
}
void dfs2(int i,int j,int d)   //右转深搜
{
    step2++;
    if(i==ex&&j==ey)return ;
    if(d==0)
    {
        if(mark[i][j+1])dfs2(i,j+1,3);
        else if(mark[i-1][j])dfs2(i-1,j,0);
        else if(mark[i][j-1])dfs2(i,j-1,1);
        else dfs2(i+1,j,2);
    }
    if(d==1)
    {
        if(mark[i-1][j])dfs2(i-1,j,0);
        else if(mark[i][j-1])dfs2(i,j-1,1);
        else if(mark[i+1][j])dfs2(i+1,j,2);
        else dfs2(i,j+1,3);
    }
    if(d==2)
    {
        if(mark[i][j-1])dfs2(i,j-1,1);
        else if(mark[i+1][j])dfs2(i+1,j,2);
        else if(mark[i][j+1])dfs2(i,j+1,3);
        else dfs2(i-1,j,0);
    }
    if(d==3)
    {
        if(mark[i+1][j])dfs2(i+1,j,2);
        else if(mark[i][j+1])dfs2(i,j+1,3);
        else if(mark[i-1][j])dfs2(i-1,j,0);
        else dfs2(i,j-1,1);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(mark,0,sizeof(mark));
        int dfscur;
        scanf("%d%d",&m,&n);
        for(int i=0;i<n;i++)
        {
            scanf("%s",a[i]);
            for(int j=0;j<m;j++)
            {
                if(a[i][j]=='.')
                {
                    mark[i][j]=1;
                }
                if(a[i][j]=='S')
                {
                   x=i;
                   y=j;
                   if(i==n-1)
                   dfscur=0;
                   else if(j==m-1)
                   dfscur=1;
                   else if(i==0)
                   dfscur=2;
                   else if(j==0)
                   dfscur=3;
                }
                if(a[i][j]=='E')
                {
                    mark[i][j]=1;
                    ex=i;
                    ey=j;
                }
            }
        }
        step=1,step2=1;
        switch(dfscur)   //左优先深搜
        {
            case 0:dfs(x-1,y,0);break;
            case 1:dfs(x,y-1,1);break;
            case 2:dfs(x+1,y,2);break;
            case 3:dfs(x,y+1,3);break;
        }
        printf("%d ",step);   //右优先深搜
        switch(dfscur)
        {
            case 0:dfs2(x-1,y,0);break;
            case 1:dfs2(x,y-1,1);break;
            case 2:dfs2(x+1,y,2);break;
            case 3:dfs2(x,y+1,3);break;
        }
        printf("%d ",step2);
        printf("%d\n",bfs(x,y));   //最短路广搜
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值